forked from GNUsocial/gnu-social
		
	
		
			
	
	
		
			592 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			592 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|   | <?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\Mapping; | ||
|  | 
 | ||
|  | use Symfony\Component\Validator\Constraint; | ||
|  | use Symfony\Component\Validator\Constraints\GroupSequence; | ||
|  | use Symfony\Component\Validator\Constraints\Traverse; | ||
|  | use Symfony\Component\Validator\Constraints\Valid; | ||
|  | use Symfony\Component\Validator\Exception\ConstraintDefinitionException; | ||
|  | use Symfony\Component\Validator\Exception\GroupDefinitionException; | ||
|  | use Symfony\Component\Validator\ValidationVisitorInterface; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Default implementation of {@link ClassMetadataInterface}. | ||
|  |  * | ||
|  |  * This class supports serialization and cloning. | ||
|  |  * | ||
|  |  * @author Bernhard Schussek <bschussek@gmail.com> | ||
|  |  * @author Fabien Potencier <fabien@symfony.com> | ||
|  |  */ | ||
|  | class ClassMetadata extends ElementMetadata implements ClassMetadataInterface | ||
|  | { | ||
|  |     /** | ||
|  |      * @var string | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link getClassName()} instead. | ||
|  |      */ | ||
|  |     public $name; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var string | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link getDefaultGroup()} instead. | ||
|  |      */ | ||
|  |     public $defaultGroup; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var MemberMetadata[][] | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link getPropertyMetadata()} instead. | ||
|  |      */ | ||
|  |     public $members = array(); | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var PropertyMetadata[] | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link getPropertyMetadata()} instead. | ||
|  |      */ | ||
|  |     public $properties = array(); | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var GetterMetadata[] | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link getPropertyMetadata()} instead. | ||
|  |      */ | ||
|  |     public $getters = array(); | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var array | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link getGroupSequence()} instead. | ||
|  |      */ | ||
|  |     public $groupSequence = array(); | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var bool | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link isGroupSequenceProvider()} instead. | ||
|  |      */ | ||
|  |     public $groupSequenceProvider = false; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The strategy for traversing traversable objects. | ||
|  |      * | ||
|  |      * By default, only instances of {@link \Traversable} are traversed. | ||
|  |      * | ||
|  |      * @var int | ||
|  |      * | ||
|  |      * @internal This property is public in order to reduce the size of the | ||
|  |      *           class' serialized representation. Do not access it. Use | ||
|  |      *           {@link getTraversalStrategy()} instead. | ||
|  |      */ | ||
|  |     public $traversalStrategy = TraversalStrategy::IMPLICIT; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var \ReflectionClass | ||
|  |      */ | ||
|  |     private $reflClass; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Constructs a metadata for the given class. | ||
|  |      * | ||
|  |      * @param string $class | ||
|  |      */ | ||
|  |     public function __construct($class) | ||
|  |     { | ||
|  |         $this->name = $class; | ||
|  |         // class name without namespace
 | ||
|  |         if (false !== $nsSep = strrpos($class, '\\')) { | ||
|  |             $this->defaultGroup = substr($class, $nsSep + 1); | ||
|  |         } else { | ||
|  |             $this->defaultGroup = $class; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      * | ||
|  |      * @deprecated since version 2.5, to be removed in 3.0. | ||
|  |      */ | ||
|  |     public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath, $propagatedGroup = null) | ||
|  |     { | ||
|  |         @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); | ||
|  | 
 | ||
|  |         if (null === $propagatedGroup && Constraint::DEFAULT_GROUP === $group | ||
|  |                 && ($this->hasGroupSequence() || $this->isGroupSequenceProvider())) { | ||
|  |             if ($this->hasGroupSequence()) { | ||
|  |                 $groups = $this->getGroupSequence()->groups; | ||
|  |             } else { | ||
|  |                 $groups = $value->getGroupSequence(); | ||
|  |             } | ||
|  | 
 | ||
|  |             foreach ($groups as $group) { | ||
|  |                 $this->accept($visitor, $value, $group, $propertyPath, Constraint::DEFAULT_GROUP); | ||
|  | 
 | ||
|  |                 if (\count($visitor->getViolations()) > 0) { | ||
|  |                     break; | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             return; | ||
|  |         } | ||
|  | 
 | ||
|  |         $visitor->visit($this, $value, $group, $propertyPath); | ||
|  | 
 | ||
|  |         if (null !== $value) { | ||
|  |             $pathPrefix = empty($propertyPath) ? '' : $propertyPath.'.'; | ||
|  | 
 | ||
|  |             foreach ($this->getConstrainedProperties() as $property) { | ||
|  |                 foreach ($this->getPropertyMetadata($property) as $member) { | ||
|  |                     $member->accept($visitor, $member->getPropertyValue($value), $group, $pathPrefix.$property, $propagatedGroup); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function __sleep() | ||
|  |     { | ||
|  |         $parentProperties = parent::__sleep(); | ||
|  | 
 | ||
|  |         // Don't store the cascading strategy. Classes never cascade.
 | ||
|  |         unset($parentProperties[array_search('cascadingStrategy', $parentProperties)]); | ||
|  | 
 | ||
|  |         return array_merge($parentProperties, array( | ||
|  |             'getters', | ||
|  |             'groupSequence', | ||
|  |             'groupSequenceProvider', | ||
|  |             'members', | ||
|  |             'name', | ||
|  |             'properties', | ||
|  |             'defaultGroup', | ||
|  |         )); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function getClassName() | ||
|  |     { | ||
|  |         return $this->name; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Returns the name of the default group for this class. | ||
|  |      * | ||
|  |      * For each class, the group "Default" is an alias for the group | ||
|  |      * "<ClassName>", where <ClassName> is the non-namespaced name of the | ||
|  |      * class. All constraints implicitly or explicitly assigned to group | ||
|  |      * "Default" belong to both of these groups, unless the class defines | ||
|  |      * a group sequence. | ||
|  |      * | ||
|  |      * If a class defines a group sequence, validating the class in "Default" | ||
|  |      * will validate the group sequence. The constraints assigned to "Default" | ||
|  |      * can still be validated by validating the class in "<ClassName>". | ||
|  |      * | ||
|  |      * @return string The name of the default group | ||
|  |      */ | ||
|  |     public function getDefaultGroup() | ||
|  |     { | ||
|  |         return $this->defaultGroup; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function addConstraint(Constraint $constraint) | ||
|  |     { | ||
|  |         if (!\in_array(Constraint::CLASS_CONSTRAINT, (array) $constraint->getTargets())) { | ||
|  |             throw new ConstraintDefinitionException(sprintf('The constraint "%s" cannot be put on classes.', \get_class($constraint))); | ||
|  |         } | ||
|  | 
 | ||
|  |         if ($constraint instanceof Valid) { | ||
|  |             throw new ConstraintDefinitionException(sprintf('The constraint "%s" cannot be put on classes.', \get_class($constraint))); | ||
|  |         } | ||
|  | 
 | ||
|  |         if ($constraint instanceof Traverse) { | ||
|  |             if ($constraint->traverse) { | ||
|  |                 // If traverse is true, traversal should be explicitly enabled
 | ||
|  |                 $this->traversalStrategy = TraversalStrategy::TRAVERSE; | ||
|  |             } else { | ||
|  |                 // If traverse is false, traversal should be explicitly disabled
 | ||
|  |                 $this->traversalStrategy = TraversalStrategy::NONE; | ||
|  |             } | ||
|  | 
 | ||
|  |             // The constraint is not added
 | ||
|  |             return $this; | ||
|  |         } | ||
|  | 
 | ||
|  |         $constraint->addImplicitGroupName($this->getDefaultGroup()); | ||
|  | 
 | ||
|  |         parent::addConstraint($constraint); | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Adds a constraint to the given property. | ||
|  |      * | ||
|  |      * @param string     $property   The name of the property | ||
|  |      * @param Constraint $constraint The constraint | ||
|  |      * | ||
|  |      * @return $this | ||
|  |      */ | ||
|  |     public function addPropertyConstraint($property, Constraint $constraint) | ||
|  |     { | ||
|  |         if (!isset($this->properties[$property])) { | ||
|  |             $this->properties[$property] = new PropertyMetadata($this->getClassName(), $property); | ||
|  | 
 | ||
|  |             $this->addPropertyMetadata($this->properties[$property]); | ||
|  |         } | ||
|  | 
 | ||
|  |         $constraint->addImplicitGroupName($this->getDefaultGroup()); | ||
|  | 
 | ||
|  |         $this->properties[$property]->addConstraint($constraint); | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @param string       $property | ||
|  |      * @param Constraint[] $constraints | ||
|  |      * | ||
|  |      * @return $this | ||
|  |      */ | ||
|  |     public function addPropertyConstraints($property, array $constraints) | ||
|  |     { | ||
|  |         foreach ($constraints as $constraint) { | ||
|  |             $this->addPropertyConstraint($property, $constraint); | ||
|  |         } | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Adds a constraint to the getter of the given property. | ||
|  |      * | ||
|  |      * The name of the getter is assumed to be the name of the property with an | ||
|  |      * uppercased first letter and either the prefix "get" or "is". | ||
|  |      * | ||
|  |      * @param string     $property   The name of the property | ||
|  |      * @param Constraint $constraint The constraint | ||
|  |      * | ||
|  |      * @return $this | ||
|  |      */ | ||
|  |     public function addGetterConstraint($property, Constraint $constraint) | ||
|  |     { | ||
|  |         if (!isset($this->getters[$property])) { | ||
|  |             $this->getters[$property] = new GetterMetadata($this->getClassName(), $property); | ||
|  | 
 | ||
|  |             $this->addPropertyMetadata($this->getters[$property]); | ||
|  |         } | ||
|  | 
 | ||
|  |         $constraint->addImplicitGroupName($this->getDefaultGroup()); | ||
|  | 
 | ||
|  |         $this->getters[$property]->addConstraint($constraint); | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Adds a constraint to the getter of the given property. | ||
|  |      * | ||
|  |      * @param string     $property   The name of the property | ||
|  |      * @param string     $method     The name of the getter method | ||
|  |      * @param Constraint $constraint The constraint | ||
|  |      * | ||
|  |      * @return $this | ||
|  |      */ | ||
|  |     public function addGetterMethodConstraint($property, $method, Constraint $constraint) | ||
|  |     { | ||
|  |         if (!isset($this->getters[$property])) { | ||
|  |             $this->getters[$property] = new GetterMetadata($this->getClassName(), $property, $method); | ||
|  | 
 | ||
|  |             $this->addPropertyMetadata($this->getters[$property]); | ||
|  |         } | ||
|  | 
 | ||
|  |         $constraint->addImplicitGroupName($this->getDefaultGroup()); | ||
|  | 
 | ||
|  |         $this->getters[$property]->addConstraint($constraint); | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @param string       $property | ||
|  |      * @param Constraint[] $constraints | ||
|  |      * | ||
|  |      * @return $this | ||
|  |      */ | ||
|  |     public function addGetterConstraints($property, array $constraints) | ||
|  |     { | ||
|  |         foreach ($constraints as $constraint) { | ||
|  |             $this->addGetterConstraint($property, $constraint); | ||
|  |         } | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @param string       $property | ||
|  |      * @param string       $method | ||
|  |      * @param Constraint[] $constraints | ||
|  |      * | ||
|  |      * @return $this | ||
|  |      */ | ||
|  |     public function addGetterMethodConstraints($property, $method, array $constraints) | ||
|  |     { | ||
|  |         foreach ($constraints as $constraint) { | ||
|  |             $this->addGetterMethodConstraint($property, $method, $constraint); | ||
|  |         } | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Merges the constraints of the given metadata into this object. | ||
|  |      */ | ||
|  |     public function mergeConstraints(ClassMetadata $source) | ||
|  |     { | ||
|  |         if ($source->isGroupSequenceProvider()) { | ||
|  |             $this->setGroupSequenceProvider(true); | ||
|  |         } | ||
|  | 
 | ||
|  |         foreach ($source->getConstraints() as $constraint) { | ||
|  |             $this->addConstraint(clone $constraint); | ||
|  |         } | ||
|  | 
 | ||
|  |         foreach ($source->getConstrainedProperties() as $property) { | ||
|  |             foreach ($source->getPropertyMetadata($property) as $member) { | ||
|  |                 $member = clone $member; | ||
|  | 
 | ||
|  |                 foreach ($member->getConstraints() as $constraint) { | ||
|  |                     if (\in_array($constraint::DEFAULT_GROUP, $constraint->groups, true)) { | ||
|  |                         $member->constraintsByGroup[$this->getDefaultGroup()][] = $constraint; | ||
|  |                     } | ||
|  | 
 | ||
|  |                     $constraint->addImplicitGroupName($this->getDefaultGroup()); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 $this->addPropertyMetadata($member); | ||
|  | 
 | ||
|  |                 if ($member instanceof MemberMetadata && !$member->isPrivate($this->name)) { | ||
|  |                     $property = $member->getPropertyName(); | ||
|  | 
 | ||
|  |                     if ($member instanceof PropertyMetadata && !isset($this->properties[$property])) { | ||
|  |                         $this->properties[$property] = $member; | ||
|  |                     } elseif ($member instanceof GetterMetadata && !isset($this->getters[$property])) { | ||
|  |                         $this->getters[$property] = $member; | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Adds a member metadata. | ||
|  |      * | ||
|  |      * @param MemberMetadata $metadata | ||
|  |      * | ||
|  |      * @deprecated since version 2.6, to be removed in 3.0. | ||
|  |      */ | ||
|  |     protected function addMemberMetadata(MemberMetadata $metadata) | ||
|  |     { | ||
|  |         @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the addPropertyMetadata() method instead.', E_USER_DEPRECATED); | ||
|  | 
 | ||
|  |         $this->addPropertyMetadata($metadata); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Returns true if metadatas of members is present for the given property. | ||
|  |      * | ||
|  |      * @param string $property The name of the property | ||
|  |      * | ||
|  |      * @return bool | ||
|  |      * | ||
|  |      * @deprecated since version 2.6, to be removed in 3.0. Use {@link hasPropertyMetadata} instead. | ||
|  |      */ | ||
|  |     public function hasMemberMetadatas($property) | ||
|  |     { | ||
|  |         @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the hasPropertyMetadata() method instead.', E_USER_DEPRECATED); | ||
|  | 
 | ||
|  |         return $this->hasPropertyMetadata($property); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Returns all metadatas of members describing the given property. | ||
|  |      * | ||
|  |      * @param string $property The name of the property | ||
|  |      * | ||
|  |      * @return MemberMetadata[] An array of MemberMetadata | ||
|  |      * | ||
|  |      * @deprecated since version 2.6, to be removed in 3.0. Use {@link getPropertyMetadata} instead. | ||
|  |      */ | ||
|  |     public function getMemberMetadatas($property) | ||
|  |     { | ||
|  |         @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the getPropertyMetadata() method instead.', E_USER_DEPRECATED); | ||
|  | 
 | ||
|  |         return $this->getPropertyMetadata($property); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function hasPropertyMetadata($property) | ||
|  |     { | ||
|  |         return array_key_exists($property, $this->members); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function getPropertyMetadata($property) | ||
|  |     { | ||
|  |         if (!isset($this->members[$property])) { | ||
|  |             return array(); | ||
|  |         } | ||
|  | 
 | ||
|  |         return $this->members[$property]; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function getConstrainedProperties() | ||
|  |     { | ||
|  |         return array_keys($this->members); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Sets the default group sequence for this class. | ||
|  |      * | ||
|  |      * @param string[]|GroupSequence $groupSequence An array of group names | ||
|  |      * | ||
|  |      * @return $this | ||
|  |      * | ||
|  |      * @throws GroupDefinitionException | ||
|  |      */ | ||
|  |     public function setGroupSequence($groupSequence) | ||
|  |     { | ||
|  |         if ($this->isGroupSequenceProvider()) { | ||
|  |             throw new GroupDefinitionException('Defining a static group sequence is not allowed with a group sequence provider'); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (\is_array($groupSequence)) { | ||
|  |             $groupSequence = new GroupSequence($groupSequence); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (\in_array(Constraint::DEFAULT_GROUP, $groupSequence->groups, true)) { | ||
|  |             throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP)); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (!\in_array($this->getDefaultGroup(), $groupSequence->groups, true)) { | ||
|  |             throw new GroupDefinitionException(sprintf('The group "%s" is missing in the group sequence', $this->getDefaultGroup())); | ||
|  |         } | ||
|  | 
 | ||
|  |         $this->groupSequence = $groupSequence; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function hasGroupSequence() | ||
|  |     { | ||
|  |         return $this->groupSequence && \count($this->groupSequence->groups) > 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function getGroupSequence() | ||
|  |     { | ||
|  |         return $this->groupSequence; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Returns a ReflectionClass instance for this class. | ||
|  |      * | ||
|  |      * @return \ReflectionClass | ||
|  |      */ | ||
|  |     public function getReflectionClass() | ||
|  |     { | ||
|  |         if (!$this->reflClass) { | ||
|  |             $this->reflClass = new \ReflectionClass($this->getClassName()); | ||
|  |         } | ||
|  | 
 | ||
|  |         return $this->reflClass; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Sets whether a group sequence provider should be used. | ||
|  |      * | ||
|  |      * @param bool $active | ||
|  |      * | ||
|  |      * @throws GroupDefinitionException | ||
|  |      */ | ||
|  |     public function setGroupSequenceProvider($active) | ||
|  |     { | ||
|  |         if ($this->hasGroupSequence()) { | ||
|  |             throw new GroupDefinitionException('Defining a group sequence provider is not allowed with a static group sequence'); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (!$this->getReflectionClass()->implementsInterface('Symfony\Component\Validator\GroupSequenceProviderInterface')) { | ||
|  |             throw new GroupDefinitionException(sprintf('Class "%s" must implement GroupSequenceProviderInterface', $this->name)); | ||
|  |         } | ||
|  | 
 | ||
|  |         $this->groupSequenceProvider = $active; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function isGroupSequenceProvider() | ||
|  |     { | ||
|  |         return $this->groupSequenceProvider; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Class nodes are never cascaded. | ||
|  |      * | ||
|  |      * {@inheritdoc} | ||
|  |      */ | ||
|  |     public function getCascadingStrategy() | ||
|  |     { | ||
|  |         return CascadingStrategy::NONE; | ||
|  |     } | ||
|  | 
 | ||
|  |     private function addPropertyMetadata(PropertyMetadataInterface $metadata) | ||
|  |     { | ||
|  |         $property = $metadata->getPropertyName(); | ||
|  | 
 | ||
|  |         $this->members[$property][] = $metadata; | ||
|  |     } | ||
|  | } |