1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\Validator\Validator; 13 14use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; 15use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface; 16use Symfony\Component\Validator\Context\ExecutionContextInterface; 17use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; 18use Symfony\Component\Validator\ObjectInitializerInterface; 19 20/** 21 * Recursive implementation of {@link ValidatorInterface}. 22 * 23 * @author Bernhard Schussek <bschussek@gmail.com> 24 */ 25class RecursiveValidator implements ValidatorInterface 26{ 27 protected $contextFactory; 28 protected $metadataFactory; 29 protected $validatorFactory; 30 protected $objectInitializers; 31 32 /** 33 * Creates a new validator. 34 * 35 * @param ExecutionContextFactoryInterface $contextFactory The factory for 36 * creating new contexts 37 * @param MetadataFactoryInterface $metadataFactory The factory for 38 * fetching the metadata 39 * of validated objects 40 * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating 41 * constraint validators 42 * @param ObjectInitializerInterface[] $objectInitializers The object initializers 43 */ 44 public function __construct(ExecutionContextFactoryInterface $contextFactory, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = []) 45 { 46 $this->contextFactory = $contextFactory; 47 $this->metadataFactory = $metadataFactory; 48 $this->validatorFactory = $validatorFactory; 49 $this->objectInitializers = $objectInitializers; 50 } 51 52 /** 53 * {@inheritdoc} 54 */ 55 public function startContext($root = null) 56 { 57 return new RecursiveContextualValidator( 58 $this->contextFactory->createContext($this, $root), 59 $this->metadataFactory, 60 $this->validatorFactory, 61 $this->objectInitializers 62 ); 63 } 64 65 /** 66 * {@inheritdoc} 67 */ 68 public function inContext(ExecutionContextInterface $context) 69 { 70 return new RecursiveContextualValidator( 71 $context, 72 $this->metadataFactory, 73 $this->validatorFactory, 74 $this->objectInitializers 75 ); 76 } 77 78 /** 79 * {@inheritdoc} 80 */ 81 public function getMetadataFor($object) 82 { 83 return $this->metadataFactory->getMetadataFor($object); 84 } 85 86 /** 87 * {@inheritdoc} 88 */ 89 public function hasMetadataFor($object) 90 { 91 return $this->metadataFactory->hasMetadataFor($object); 92 } 93 94 /** 95 * {@inheritdoc} 96 */ 97 public function validate($value, $constraints = null, $groups = null) 98 { 99 return $this->startContext($value) 100 ->validate($value, $constraints, $groups) 101 ->getViolations(); 102 } 103 104 /** 105 * {@inheritdoc} 106 */ 107 public function validateProperty($object, $propertyName, $groups = null) 108 { 109 return $this->startContext($object) 110 ->validateProperty($object, $propertyName, $groups) 111 ->getViolations(); 112 } 113 114 /** 115 * {@inheritdoc} 116 */ 117 public function validatePropertyValue($objectOrClass, $propertyName, $value, $groups = null) 118 { 119 // If a class name is passed, take $value as root 120 return $this->startContext(\is_object($objectOrClass) ? $objectOrClass : $value) 121 ->validatePropertyValue($objectOrClass, $propertyName, $value, $groups) 122 ->getViolations(); 123 } 124} 125