4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Validator;
14 @trigger_error('The '.__NAMESPACE__.'\Validator class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Validator\Validator\RecursiveValidator class instead.', E_USER_DEPRECATED);
16 use Symfony\Component\Translation\TranslatorInterface;
17 use Symfony\Component\Validator\Constraints\Valid;
18 use Symfony\Component\Validator\Exception\ValidatorException;
21 * Default implementation of {@link ValidatorInterface}.
23 * @author Fabien Potencier <fabien@symfony.com>
24 * @author Bernhard Schussek <bschussek@gmail.com>
26 * @deprecated since version 2.5, to be removed in 3.0.
27 * Use {@link Validator\RecursiveValidator} instead.
29 class Validator implements ValidatorInterface, Mapping\Factory\MetadataFactoryInterface
32 * @var MetadataFactoryInterface
34 private $metadataFactory;
37 * @var ConstraintValidatorFactoryInterface
39 private $validatorFactory;
42 * @var TranslatorInterface
49 private $translationDomain;
54 private $objectInitializers;
56 public function __construct(
57 MetadataFactoryInterface $metadataFactory,
58 ConstraintValidatorFactoryInterface $validatorFactory,
59 TranslatorInterface $translator,
60 $translationDomain = 'validators',
61 array $objectInitializers = array()
63 $this->metadataFactory = $metadataFactory;
64 $this->validatorFactory = $validatorFactory;
65 $this->translator = $translator;
66 $this->translationDomain = $translationDomain;
67 $this->objectInitializers = $objectInitializers;
73 public function getMetadataFactory()
75 return $this->metadataFactory;
81 public function getMetadataFor($value)
83 return $this->metadataFactory->getMetadataFor($value);
89 public function hasMetadataFor($value)
91 return $this->metadataFactory->hasMetadataFor($value);
97 public function validate($value, $groups = null, $traverse = false, $deep = false)
99 $visitor = $this->createVisitor($value);
101 foreach ($this->resolveGroups($groups) as $group) {
102 $visitor->validate($value, $group, '', $traverse, $deep);
105 return $visitor->getViolations();
111 * @throws ValidatorException If the metadata for the value does not support properties.
113 public function validateProperty($containingValue, $property, $groups = null)
115 $visitor = $this->createVisitor($containingValue);
116 $metadata = $this->metadataFactory->getMetadataFor($containingValue);
118 if (!$metadata instanceof PropertyMetadataContainerInterface) {
119 $valueAsString = is_scalar($containingValue)
120 ? '"'.$containingValue.'"'
121 : 'the value of type '.gettype($containingValue);
123 throw new ValidatorException(sprintf('The metadata for %s does not support properties.', $valueAsString));
126 foreach ($this->resolveGroups($groups) as $group) {
127 if (!$metadata->hasPropertyMetadata($property)) {
131 foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
132 $propMeta->accept($visitor, $propMeta->getPropertyValue($containingValue), $group, $property);
136 return $visitor->getViolations();
142 * @throws ValidatorException If the metadata for the value does not support properties.
144 public function validatePropertyValue($containingValue, $property, $value, $groups = null)
146 $visitor = $this->createVisitor(is_object($containingValue) ? $containingValue : $value);
147 $metadata = $this->metadataFactory->getMetadataFor($containingValue);
149 if (!$metadata instanceof PropertyMetadataContainerInterface) {
150 $valueAsString = is_scalar($containingValue)
151 ? '"'.$containingValue.'"'
152 : 'the value of type '.gettype($containingValue);
154 throw new ValidatorException(sprintf('The metadata for '.$valueAsString.' does not support properties.'));
157 // If $containingValue is passed as class name, take $value as root
158 // and start the traversal with an empty property path
159 $propertyPath = is_object($containingValue) ? $property : '';
161 foreach ($this->resolveGroups($groups) as $group) {
162 if (!$metadata->hasPropertyMetadata($property)) {
166 foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
167 $propMeta->accept($visitor, $value, $group, $propertyPath);
171 return $visitor->getViolations();
177 public function validateValue($value, $constraints, $groups = null)
179 $context = new ExecutionContext($this->createVisitor($value), $this->translator, $this->translationDomain);
181 $constraints = is_array($constraints) ? $constraints : array($constraints);
183 foreach ($constraints as $constraint) {
184 if ($constraint instanceof Valid) {
185 // Why can't the Valid constraint be executed directly?
187 // It cannot be executed like regular other constraints, because regular
188 // constraints are only executed *if they belong to the validated group*.
189 // The Valid constraint, on the other hand, is always executed and propagates
190 // the group to the cascaded object. The propagated group depends on
192 // * Whether a group sequence is currently being executed. Then the default
193 // group is propagated.
195 // * Otherwise the validated group is propagated.
197 throw new ValidatorException(
199 'The constraint %s cannot be validated. Use the method validate() instead.',
200 get_class($constraint)
205 $context->validateValue($value, $constraint, '', $groups);
208 return $context->getViolations();
214 * @return ValidationVisitor
216 private function createVisitor($root)
218 return new ValidationVisitor(
220 $this->metadataFactory,
221 $this->validatorFactory,
223 $this->translationDomain,
224 $this->objectInitializers
229 * @param null|string|string[] $groups
233 private function resolveGroups($groups)
235 return $groups ? (array) $groups : array(Constraint::DEFAULT_GROUP);