Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\Validator\Mapping; Chris@0: Chris@0: use Symfony\Component\Validator\Constraint; Chris@0: use Symfony\Component\Validator\Constraints\Traverse; Chris@0: use Symfony\Component\Validator\Constraints\Valid; Chris@0: use Symfony\Component\Validator\Exception\ConstraintDefinitionException; Chris@0: Chris@0: /** Chris@0: * A generic container of {@link Constraint} objects. Chris@0: * Chris@0: * This class supports serialization and cloning. Chris@0: * Chris@0: * @author Bernhard Schussek Chris@0: */ Chris@0: class GenericMetadata implements MetadataInterface Chris@0: { Chris@0: /** Chris@0: * @var Constraint[] Chris@0: * Chris@0: * @internal This property is public in order to reduce the size of the Chris@0: * class' serialized representation. Do not access it. Use Chris@0: * {@link getConstraints()} and {@link findConstraints()} instead. Chris@0: */ Chris@17: public $constraints = []; Chris@0: Chris@0: /** Chris@0: * @var array Chris@0: * Chris@0: * @internal This property is public in order to reduce the size of the Chris@0: * class' serialized representation. Do not access it. Use Chris@0: * {@link findConstraints()} instead. Chris@0: */ Chris@17: public $constraintsByGroup = []; Chris@0: Chris@0: /** Chris@0: * The strategy for cascading objects. Chris@0: * Chris@0: * By default, objects are not cascaded. Chris@0: * Chris@0: * @var int Chris@0: * Chris@0: * @see CascadingStrategy Chris@0: * Chris@0: * @internal This property is public in order to reduce the size of the Chris@0: * class' serialized representation. Do not access it. Use Chris@0: * {@link getCascadingStrategy()} instead. Chris@0: */ Chris@0: public $cascadingStrategy = CascadingStrategy::NONE; Chris@0: Chris@0: /** Chris@0: * The strategy for traversing traversable objects. Chris@0: * Chris@0: * By default, traversable objects are not traversed. Chris@0: * Chris@0: * @var int Chris@0: * Chris@0: * @see TraversalStrategy Chris@0: * Chris@0: * @internal This property is public in order to reduce the size of the Chris@0: * class' serialized representation. Do not access it. Use Chris@0: * {@link getTraversalStrategy()} instead. Chris@0: */ Chris@0: public $traversalStrategy = TraversalStrategy::NONE; Chris@0: Chris@0: /** Chris@0: * Returns the names of the properties that should be serialized. Chris@0: * Chris@0: * @return string[] Chris@0: */ Chris@0: public function __sleep() Chris@0: { Chris@17: return [ Chris@0: 'constraints', Chris@0: 'constraintsByGroup', Chris@0: 'cascadingStrategy', Chris@0: 'traversalStrategy', Chris@17: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clones this object. Chris@0: */ Chris@0: public function __clone() Chris@0: { Chris@0: $constraints = $this->constraints; Chris@0: Chris@17: $this->constraints = []; Chris@17: $this->constraintsByGroup = []; Chris@0: Chris@0: foreach ($constraints as $constraint) { Chris@0: $this->addConstraint(clone $constraint); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a constraint. Chris@0: * Chris@0: * If the constraint {@link Valid} is added, the cascading strategy will be Chris@0: * changed to {@link CascadingStrategy::CASCADE}. Depending on the Chris@0: * $traverse property of that constraint, the traversal strategy Chris@0: * will be set to one of the following: Chris@0: * Chris@0: * - {@link TraversalStrategy::IMPLICIT} if $traverse is enabled Chris@0: * - {@link TraversalStrategy::NONE} if $traverse is disabled Chris@0: * Chris@0: * @return $this Chris@0: * Chris@0: * @throws ConstraintDefinitionException When trying to add the Chris@0: * {@link Traverse} constraint Chris@0: */ Chris@0: public function addConstraint(Constraint $constraint) Chris@0: { Chris@0: if ($constraint instanceof Traverse) { Chris@17: throw new ConstraintDefinitionException(sprintf('The constraint "%s" can only be put on classes. Please use "Symfony\Component\Validator\Constraints\Valid" instead.', \get_class($constraint))); Chris@0: } Chris@0: Chris@14: if ($constraint instanceof Valid && null === $constraint->groups) { Chris@0: $this->cascadingStrategy = CascadingStrategy::CASCADE; Chris@0: Chris@0: if ($constraint->traverse) { Chris@0: $this->traversalStrategy = TraversalStrategy::IMPLICIT; Chris@0: } else { Chris@0: $this->traversalStrategy = TraversalStrategy::NONE; Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: $this->constraints[] = $constraint; Chris@0: Chris@0: foreach ($constraint->groups as $group) { Chris@0: $this->constraintsByGroup[$group][] = $constraint; Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds an list of constraints. Chris@0: * Chris@0: * @param Constraint[] $constraints The constraints to add Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function addConstraints(array $constraints) Chris@0: { Chris@0: foreach ($constraints as $constraint) { Chris@0: $this->addConstraint($constraint); Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getConstraints() Chris@0: { Chris@0: return $this->constraints; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns whether this element has any constraints. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function hasConstraints() Chris@0: { Chris@17: return \count($this->constraints) > 0; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * Chris@0: * Aware of the global group (* group). Chris@0: */ Chris@0: public function findConstraints($group) Chris@0: { Chris@0: return isset($this->constraintsByGroup[$group]) Chris@0: ? $this->constraintsByGroup[$group] Chris@17: : []; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getCascadingStrategy() Chris@0: { Chris@0: return $this->cascadingStrategy; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getTraversalStrategy() Chris@0: { Chris@0: return $this->traversalStrategy; Chris@0: } Chris@0: }