Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\Validator\Constraints;
|
Chris@0
|
13
|
Chris@0
|
14 use Symfony\Component\Validator\Constraint;
|
Chris@0
|
15 use Symfony\Component\Validator\ConstraintValidator;
|
Chris@0
|
16 use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
Chris@0
|
17 use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
Chris@0
|
18
|
Chris@0
|
19 /**
|
Chris@0
|
20 * ChoiceValidator validates that the value is one of the expected values.
|
Chris@0
|
21 *
|
Chris@0
|
22 * @author Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
23 * @author Florian Eckerstorfer <florian@eckerstorfer.org>
|
Chris@0
|
24 * @author Bernhard Schussek <bschussek@gmail.com>
|
Chris@0
|
25 */
|
Chris@0
|
26 class ChoiceValidator extends ConstraintValidator
|
Chris@0
|
27 {
|
Chris@0
|
28 /**
|
Chris@0
|
29 * {@inheritdoc}
|
Chris@0
|
30 */
|
Chris@0
|
31 public function validate($value, Constraint $constraint)
|
Chris@0
|
32 {
|
Chris@0
|
33 if (!$constraint instanceof Choice) {
|
Chris@0
|
34 throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Choice');
|
Chris@0
|
35 }
|
Chris@0
|
36
|
Chris@17
|
37 if (!\is_array($constraint->choices) && !$constraint->callback) {
|
Chris@0
|
38 throw new ConstraintDefinitionException('Either "choices" or "callback" must be specified on constraint Choice');
|
Chris@0
|
39 }
|
Chris@0
|
40
|
Chris@0
|
41 if (null === $value) {
|
Chris@0
|
42 return;
|
Chris@0
|
43 }
|
Chris@0
|
44
|
Chris@17
|
45 if ($constraint->multiple && !\is_array($value)) {
|
Chris@0
|
46 throw new UnexpectedTypeException($value, 'array');
|
Chris@0
|
47 }
|
Chris@0
|
48
|
Chris@0
|
49 if ($constraint->callback) {
|
Chris@17
|
50 if (!\is_callable($choices = [$this->context->getObject(), $constraint->callback])
|
Chris@17
|
51 && !\is_callable($choices = [$this->context->getClassName(), $constraint->callback])
|
Chris@17
|
52 && !\is_callable($choices = $constraint->callback)
|
Chris@0
|
53 ) {
|
Chris@0
|
54 throw new ConstraintDefinitionException('The Choice constraint expects a valid callback');
|
Chris@0
|
55 }
|
Chris@17
|
56 $choices = \call_user_func($choices);
|
Chris@0
|
57 } else {
|
Chris@0
|
58 $choices = $constraint->choices;
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@14
|
61 if (true !== $constraint->strict) {
|
Chris@14
|
62 @trigger_error('Not setting the strict option of the Choice constraint to true is deprecated since Symfony 3.4 and will throw an exception in 4.0.', E_USER_DEPRECATED);
|
Chris@0
|
63 }
|
Chris@0
|
64
|
Chris@0
|
65 if ($constraint->multiple) {
|
Chris@0
|
66 foreach ($value as $_value) {
|
Chris@17
|
67 if (!\in_array($_value, $choices, $constraint->strict)) {
|
Chris@0
|
68 $this->context->buildViolation($constraint->multipleMessage)
|
Chris@0
|
69 ->setParameter('{{ value }}', $this->formatValue($_value))
|
Chris@0
|
70 ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
|
Chris@0
|
71 ->setInvalidValue($_value)
|
Chris@0
|
72 ->addViolation();
|
Chris@0
|
73
|
Chris@0
|
74 return;
|
Chris@0
|
75 }
|
Chris@0
|
76 }
|
Chris@0
|
77
|
Chris@17
|
78 $count = \count($value);
|
Chris@0
|
79
|
Chris@14
|
80 if (null !== $constraint->min && $count < $constraint->min) {
|
Chris@0
|
81 $this->context->buildViolation($constraint->minMessage)
|
Chris@0
|
82 ->setParameter('{{ limit }}', $constraint->min)
|
Chris@0
|
83 ->setPlural((int) $constraint->min)
|
Chris@0
|
84 ->setCode(Choice::TOO_FEW_ERROR)
|
Chris@0
|
85 ->addViolation();
|
Chris@0
|
86
|
Chris@0
|
87 return;
|
Chris@0
|
88 }
|
Chris@0
|
89
|
Chris@14
|
90 if (null !== $constraint->max && $count > $constraint->max) {
|
Chris@0
|
91 $this->context->buildViolation($constraint->maxMessage)
|
Chris@0
|
92 ->setParameter('{{ limit }}', $constraint->max)
|
Chris@0
|
93 ->setPlural((int) $constraint->max)
|
Chris@0
|
94 ->setCode(Choice::TOO_MANY_ERROR)
|
Chris@0
|
95 ->addViolation();
|
Chris@0
|
96
|
Chris@0
|
97 return;
|
Chris@0
|
98 }
|
Chris@17
|
99 } elseif (!\in_array($value, $choices, $constraint->strict)) {
|
Chris@0
|
100 $this->context->buildViolation($constraint->message)
|
Chris@0
|
101 ->setParameter('{{ value }}', $this->formatValue($value))
|
Chris@0
|
102 ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
|
Chris@0
|
103 ->addViolation();
|
Chris@0
|
104 }
|
Chris@0
|
105 }
|
Chris@0
|
106 }
|