/**
  * {@inheritdoc}
  */
 public function validatePropertyValue($objectOrClass, $propertyName, $value, $groups = null)
 {
     $classMetadata = $this->metadataFactory->getMetadataFor($objectOrClass);
     if (!$classMetadata instanceof ClassMetadataInterface) {
         // Cannot be UnsupportedMetadataException because of BC with
         // Symfony < 2.5
         throw new ValidatorException(sprintf('The metadata factory should return instances of ' . '"\\Symfony\\Component\\Validator\\Mapping\\ClassMetadataInterface", ' . 'got: "%s".', is_object($classMetadata) ? get_class($classMetadata) : gettype($classMetadata)));
     }
     $propertyMetadatas = $classMetadata->getPropertyMetadata($propertyName);
     $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
     if (is_object($objectOrClass)) {
         $object = $objectOrClass;
         $cacheKey = spl_object_hash($objectOrClass);
         $propertyPath = PropertyPath::append($this->defaultPropertyPath, $propertyName);
     } else {
         // $objectOrClass contains a class name
         $object = null;
         $cacheKey = null;
         $propertyPath = $this->defaultPropertyPath;
     }
     $previousValue = $this->context->getValue();
     $previousObject = $this->context->getObject();
     $previousMetadata = $this->context->getMetadata();
     $previousPath = $this->context->getPropertyPath();
     $previousGroup = $this->context->getGroup();
     foreach ($propertyMetadatas as $propertyMetadata) {
         $this->validateGenericNode($value, $object, $cacheKey . ':' . $propertyName, $propertyMetadata, $propertyPath, $groups, null, TraversalStrategy::IMPLICIT, $this->context);
     }
     $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
     $this->context->setGroup($previousGroup);
     return $this;
 }
 /**
  * Creates a validator for the given context.
  *
  * @param ExecutionContextInterface           $context          The execution context
  * @param MetadataFactoryInterface            $metadataFactory  The factory for
  *                                                              fetching the metadata
  *                                                              of validated objects
  * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating
  *                                                              constraint validators
  */
 public function __construct(ExecutionContextInterface $context, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory)
 {
     $this->context = $context;
     $this->defaultPropertyPath = $context->getPropertyPath();
     $this->defaultGroups = array($context->getGroup() ?: Constraint::DEFAULT_GROUP);
     $this->metadataFactory = $metadataFactory;
     $this->validatorFactory = $validatorFactory;
 }
 function it_validates_object($constraint, NewContext $context, ValidatorInterface $validator, ContextualValidatorInterface $contextValidator)
 {
     $constraint->condition = function ($object) {
         return $object->name == 'some name';
     };
     $object = new \stdClass();
     $object->name = 'some name';
     $context->getGroup()->shouldBeCalled();
     $context->getObject()->willReturn($object);
     $context->getValidator()->willReturn($validator);
     $validator->inContext($context)->willReturn($contextValidator);
     $contextValidator->validate($object, $constraint->constraints, Argument::any())->shouldBeCalled();
     $this->initialize($context);
     $this->validate($object, $constraint);
 }
 /**
  * @param ExecutionContextInterface $context
  * @param AttributeInterface        $attribute
  * @param DataInterface             $data
  *
  * @throws Exception
  */
 protected function validateRules(ExecutionContextInterface $context, AttributeInterface $attribute, DataInterface $data)
 {
     if ($attribute->isMultiple()) {
         $valueData = $data->getValuesData($attribute);
     } else {
         $valueData = $data->getValueData($attribute);
     }
     $loader = new BaseLoader();
     foreach ($attribute->getValidationRules() as $validationRule) {
         foreach ($validationRule as $item => $options) {
             $constraint = $loader->newConstraint($item, $options);
             $violations = $context->getValidator()->validate($valueData, $constraint, $context->getGroup());
             /** @var ConstraintViolationInterface $violation */
             foreach ($violations as $violation) {
                 /** @noinspection DisconnectedForeachInstructionInspection */
                 $path = $attribute->getCode();
                 if ($attribute->getType()->isEmbedded()) {
                     if (!$attribute->isMultiple()) {
                         $path .= '.';
                     }
                     $path .= $violation->getPropertyPath();
                 }
                 if ($violation->getMessage()) {
                     $context->buildViolation($violation->getMessage())->atPath($path)->setInvalidValue($valueData)->addViolation();
                 } else {
                     $this->buildAttributeViolation($context, $attribute, strtolower($item), $valueData, $path);
                 }
             }
         }
     }
 }