Version 1
[yaffs-website] / vendor / symfony / validator / Mapping / GenericMetadata.php
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
12 namespace Symfony\Component\Validator\Mapping;
13
14 use Symfony\Component\Validator\Constraint;
15 use Symfony\Component\Validator\Constraints\Traverse;
16 use Symfony\Component\Validator\Constraints\Valid;
17 use Symfony\Component\Validator\Exception\BadMethodCallException;
18 use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
19 use Symfony\Component\Validator\ValidationVisitorInterface;
20
21 /**
22  * A generic container of {@link Constraint} objects.
23  *
24  * This class supports serialization and cloning.
25  *
26  * @author Bernhard Schussek <bschussek@gmail.com>
27  */
28 class GenericMetadata implements MetadataInterface
29 {
30     /**
31      * @var Constraint[]
32      *
33      * @internal This property is public in order to reduce the size of the
34      *           class' serialized representation. Do not access it. Use
35      *           {@link getConstraints()} and {@link findConstraints()} instead.
36      */
37     public $constraints = array();
38
39     /**
40      * @var array
41      *
42      * @internal This property is public in order to reduce the size of the
43      *           class' serialized representation. Do not access it. Use
44      *           {@link findConstraints()} instead.
45      */
46     public $constraintsByGroup = array();
47
48     /**
49      * The strategy for cascading objects.
50      *
51      * By default, objects are not cascaded.
52      *
53      * @var int
54      *
55      * @see CascadingStrategy
56      *
57      * @internal This property is public in order to reduce the size of the
58      *           class' serialized representation. Do not access it. Use
59      *           {@link getCascadingStrategy()} instead.
60      */
61     public $cascadingStrategy = CascadingStrategy::NONE;
62
63     /**
64      * The strategy for traversing traversable objects.
65      *
66      * By default, traversable objects are not traversed.
67      *
68      * @var int
69      *
70      * @see TraversalStrategy
71      *
72      * @internal This property is public in order to reduce the size of the
73      *           class' serialized representation. Do not access it. Use
74      *           {@link getTraversalStrategy()} instead.
75      */
76     public $traversalStrategy = TraversalStrategy::NONE;
77
78     /**
79      * Returns the names of the properties that should be serialized.
80      *
81      * @return string[]
82      */
83     public function __sleep()
84     {
85         return array(
86             'constraints',
87             'constraintsByGroup',
88             'cascadingStrategy',
89             'traversalStrategy',
90         );
91     }
92
93     /**
94      * Clones this object.
95      */
96     public function __clone()
97     {
98         $constraints = $this->constraints;
99
100         $this->constraints = array();
101         $this->constraintsByGroup = array();
102
103         foreach ($constraints as $constraint) {
104             $this->addConstraint(clone $constraint);
105         }
106     }
107
108     /**
109      * Adds a constraint.
110      *
111      * If the constraint {@link Valid} is added, the cascading strategy will be
112      * changed to {@link CascadingStrategy::CASCADE}. Depending on the
113      * properties $traverse and $deep of that constraint, the traversal strategy
114      * will be set to one of the following:
115      *
116      *  - {@link TraversalStrategy::IMPLICIT} if $traverse is enabled and $deep
117      *    is enabled
118      *  - {@link TraversalStrategy::IMPLICIT} | {@link TraversalStrategy::STOP_RECURSION}
119      *    if $traverse is enabled, but $deep is disabled
120      *  - {@link TraversalStrategy::NONE} if $traverse is disabled
121      *
122      * @param Constraint $constraint The constraint to add
123      *
124      * @return $this
125      *
126      * @throws ConstraintDefinitionException When trying to add the
127      *                                       {@link Traverse} constraint
128      */
129     public function addConstraint(Constraint $constraint)
130     {
131         if ($constraint instanceof Traverse) {
132             throw new ConstraintDefinitionException(sprintf(
133                 'The constraint "%s" can only be put on classes. Please use '.
134                 '"Symfony\Component\Validator\Constraints\Valid" instead.',
135                 get_class($constraint)
136             ));
137         }
138
139         if ($constraint instanceof Valid) {
140             $this->cascadingStrategy = CascadingStrategy::CASCADE;
141
142             if ($constraint->traverse) {
143                 // Traverse unless the value is not traversable
144                 $this->traversalStrategy = TraversalStrategy::IMPLICIT;
145
146                 if (!$constraint->deep) {
147                     $this->traversalStrategy |= TraversalStrategy::STOP_RECURSION;
148                 }
149             } else {
150                 $this->traversalStrategy = TraversalStrategy::NONE;
151             }
152
153             return $this;
154         }
155
156         $this->constraints[] = $constraint;
157
158         foreach ($constraint->groups as $group) {
159             $this->constraintsByGroup[$group][] = $constraint;
160         }
161
162         return $this;
163     }
164
165     /**
166      * Adds an list of constraints.
167      *
168      * @param Constraint[] $constraints The constraints to add
169      *
170      * @return $this
171      */
172     public function addConstraints(array $constraints)
173     {
174         foreach ($constraints as $constraint) {
175             $this->addConstraint($constraint);
176         }
177
178         return $this;
179     }
180
181     /**
182      * {@inheritdoc}
183      */
184     public function getConstraints()
185     {
186         return $this->constraints;
187     }
188
189     /**
190      * Returns whether this element has any constraints.
191      *
192      * @return bool
193      */
194     public function hasConstraints()
195     {
196         return count($this->constraints) > 0;
197     }
198
199     /**
200      * {@inheritdoc}
201      *
202      * Aware of the global group (* group).
203      */
204     public function findConstraints($group)
205     {
206         return isset($this->constraintsByGroup[$group])
207             ? $this->constraintsByGroup[$group]
208             : array();
209     }
210
211     /**
212      * {@inheritdoc}
213      */
214     public function getCascadingStrategy()
215     {
216         return $this->cascadingStrategy;
217     }
218
219     /**
220      * {@inheritdoc}
221      */
222     public function getTraversalStrategy()
223     {
224         return $this->traversalStrategy;
225     }
226
227     /**
228      * Exists for compatibility with the deprecated
229      * {@link Symfony\Component\Validator\MetadataInterface}.
230      *
231      * Should not be used.
232      *
233      * Implemented for backward compatibility with Symfony < 2.5.
234      *
235      * @throws BadMethodCallException
236      *
237      * @deprecated since version 2.5, to be removed in 3.0.
238      */
239     public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath)
240     {
241         throw new BadMethodCallException('Not supported.');
242     }
243 }