Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/validator/Mapping/ClassMetadata.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
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\GroupSequence; | |
16 use Symfony\Component\Validator\Constraints\Traverse; | |
17 use Symfony\Component\Validator\Constraints\Valid; | |
18 use Symfony\Component\Validator\Exception\ConstraintDefinitionException; | |
19 use Symfony\Component\Validator\Exception\GroupDefinitionException; | |
20 | |
21 /** | |
22 * Default implementation of {@link ClassMetadataInterface}. | |
23 * | |
24 * This class supports serialization and cloning. | |
25 * | |
26 * @author Bernhard Schussek <bschussek@gmail.com> | |
27 * @author Fabien Potencier <fabien@symfony.com> | |
28 */ | |
29 class ClassMetadata extends GenericMetadata implements ClassMetadataInterface | |
30 { | |
31 /** | |
32 * @var string | |
33 * | |
34 * @internal This property is public in order to reduce the size of the | |
35 * class' serialized representation. Do not access it. Use | |
36 * {@link getClassName()} instead. | |
37 */ | |
38 public $name; | |
39 | |
40 /** | |
41 * @var string | |
42 * | |
43 * @internal This property is public in order to reduce the size of the | |
44 * class' serialized representation. Do not access it. Use | |
45 * {@link getDefaultGroup()} instead. | |
46 */ | |
47 public $defaultGroup; | |
48 | |
49 /** | |
50 * @var MemberMetadata[] | |
51 * | |
52 * @internal This property is public in order to reduce the size of the | |
53 * class' serialized representation. Do not access it. Use | |
54 * {@link getPropertyMetadata()} instead. | |
55 */ | |
56 public $members = array(); | |
57 | |
58 /** | |
59 * @var PropertyMetadata[] | |
60 * | |
61 * @internal This property is public in order to reduce the size of the | |
62 * class' serialized representation. Do not access it. Use | |
63 * {@link getPropertyMetadata()} instead. | |
64 */ | |
65 public $properties = array(); | |
66 | |
67 /** | |
68 * @var GetterMetadata[] | |
69 * | |
70 * @internal This property is public in order to reduce the size of the | |
71 * class' serialized representation. Do not access it. Use | |
72 * {@link getPropertyMetadata()} instead. | |
73 */ | |
74 public $getters = array(); | |
75 | |
76 /** | |
77 * @var array | |
78 * | |
79 * @internal This property is public in order to reduce the size of the | |
80 * class' serialized representation. Do not access it. Use | |
81 * {@link getGroupSequence()} instead. | |
82 */ | |
83 public $groupSequence = array(); | |
84 | |
85 /** | |
86 * @var bool | |
87 * | |
88 * @internal This property is public in order to reduce the size of the | |
89 * class' serialized representation. Do not access it. Use | |
90 * {@link isGroupSequenceProvider()} instead. | |
91 */ | |
92 public $groupSequenceProvider = false; | |
93 | |
94 /** | |
95 * The strategy for traversing traversable objects. | |
96 * | |
97 * By default, only instances of {@link \Traversable} are traversed. | |
98 * | |
99 * @var int | |
100 * | |
101 * @internal This property is public in order to reduce the size of the | |
102 * class' serialized representation. Do not access it. Use | |
103 * {@link getTraversalStrategy()} instead. | |
104 */ | |
105 public $traversalStrategy = TraversalStrategy::IMPLICIT; | |
106 | |
107 /** | |
108 * @var \ReflectionClass | |
109 */ | |
110 private $reflClass; | |
111 | |
112 /** | |
113 * Constructs a metadata for the given class. | |
114 * | |
115 * @param string $class | |
116 */ | |
117 public function __construct($class) | |
118 { | |
119 $this->name = $class; | |
120 // class name without namespace | |
121 if (false !== $nsSep = strrpos($class, '\\')) { | |
122 $this->defaultGroup = substr($class, $nsSep + 1); | |
123 } else { | |
124 $this->defaultGroup = $class; | |
125 } | |
126 } | |
127 | |
128 /** | |
129 * {@inheritdoc} | |
130 */ | |
131 public function __sleep() | |
132 { | |
133 $parentProperties = parent::__sleep(); | |
134 | |
135 // Don't store the cascading strategy. Classes never cascade. | |
136 unset($parentProperties[array_search('cascadingStrategy', $parentProperties)]); | |
137 | |
138 return array_merge($parentProperties, array( | |
139 'getters', | |
140 'groupSequence', | |
141 'groupSequenceProvider', | |
142 'members', | |
143 'name', | |
144 'properties', | |
145 'defaultGroup', | |
146 )); | |
147 } | |
148 | |
149 /** | |
150 * {@inheritdoc} | |
151 */ | |
152 public function getClassName() | |
153 { | |
154 return $this->name; | |
155 } | |
156 | |
157 /** | |
158 * Returns the name of the default group for this class. | |
159 * | |
160 * For each class, the group "Default" is an alias for the group | |
161 * "<ClassName>", where <ClassName> is the non-namespaced name of the | |
162 * class. All constraints implicitly or explicitly assigned to group | |
163 * "Default" belong to both of these groups, unless the class defines | |
164 * a group sequence. | |
165 * | |
166 * If a class defines a group sequence, validating the class in "Default" | |
167 * will validate the group sequence. The constraints assigned to "Default" | |
168 * can still be validated by validating the class in "<ClassName>". | |
169 * | |
170 * @return string The name of the default group | |
171 */ | |
172 public function getDefaultGroup() | |
173 { | |
174 return $this->defaultGroup; | |
175 } | |
176 | |
177 /** | |
178 * {@inheritdoc} | |
179 */ | |
180 public function addConstraint(Constraint $constraint) | |
181 { | |
182 if (!in_array(Constraint::CLASS_CONSTRAINT, (array) $constraint->getTargets())) { | |
183 throw new ConstraintDefinitionException(sprintf( | |
184 'The constraint "%s" cannot be put on classes.', | |
185 get_class($constraint) | |
186 )); | |
187 } | |
188 | |
189 if ($constraint instanceof Valid) { | |
190 throw new ConstraintDefinitionException(sprintf( | |
191 'The constraint "%s" cannot be put on classes.', | |
192 get_class($constraint) | |
193 )); | |
194 } | |
195 | |
196 if ($constraint instanceof Traverse) { | |
197 if ($constraint->traverse) { | |
198 // If traverse is true, traversal should be explicitly enabled | |
199 $this->traversalStrategy = TraversalStrategy::TRAVERSE; | |
200 } else { | |
201 // If traverse is false, traversal should be explicitly disabled | |
202 $this->traversalStrategy = TraversalStrategy::NONE; | |
203 } | |
204 | |
205 // The constraint is not added | |
206 return $this; | |
207 } | |
208 | |
209 $constraint->addImplicitGroupName($this->getDefaultGroup()); | |
210 | |
211 parent::addConstraint($constraint); | |
212 | |
213 return $this; | |
214 } | |
215 | |
216 /** | |
217 * Adds a constraint to the given property. | |
218 * | |
219 * @param string $property The name of the property | |
220 * @param Constraint $constraint The constraint | |
221 * | |
222 * @return $this | |
223 */ | |
224 public function addPropertyConstraint($property, Constraint $constraint) | |
225 { | |
226 if (!isset($this->properties[$property])) { | |
227 $this->properties[$property] = new PropertyMetadata($this->getClassName(), $property); | |
228 | |
229 $this->addPropertyMetadata($this->properties[$property]); | |
230 } | |
231 | |
232 $constraint->addImplicitGroupName($this->getDefaultGroup()); | |
233 | |
234 $this->properties[$property]->addConstraint($constraint); | |
235 | |
236 return $this; | |
237 } | |
238 | |
239 /** | |
240 * @param string $property | |
241 * @param Constraint[] $constraints | |
242 * | |
243 * @return $this | |
244 */ | |
245 public function addPropertyConstraints($property, array $constraints) | |
246 { | |
247 foreach ($constraints as $constraint) { | |
248 $this->addPropertyConstraint($property, $constraint); | |
249 } | |
250 | |
251 return $this; | |
252 } | |
253 | |
254 /** | |
255 * Adds a constraint to the getter of the given property. | |
256 * | |
257 * The name of the getter is assumed to be the name of the property with an | |
258 * uppercased first letter and either the prefix "get" or "is". | |
259 * | |
260 * @param string $property The name of the property | |
261 * @param Constraint $constraint The constraint | |
262 * | |
263 * @return $this | |
264 */ | |
265 public function addGetterConstraint($property, Constraint $constraint) | |
266 { | |
267 if (!isset($this->getters[$property])) { | |
268 $this->getters[$property] = new GetterMetadata($this->getClassName(), $property); | |
269 | |
270 $this->addPropertyMetadata($this->getters[$property]); | |
271 } | |
272 | |
273 $constraint->addImplicitGroupName($this->getDefaultGroup()); | |
274 | |
275 $this->getters[$property]->addConstraint($constraint); | |
276 | |
277 return $this; | |
278 } | |
279 | |
280 /** | |
281 * Adds a constraint to the getter of the given property. | |
282 * | |
283 * @param string $property The name of the property | |
284 * @param string $method The name of the getter method | |
285 * @param Constraint $constraint The constraint | |
286 * | |
287 * @return $this | |
288 */ | |
289 public function addGetterMethodConstraint($property, $method, Constraint $constraint) | |
290 { | |
291 if (!isset($this->getters[$property])) { | |
292 $this->getters[$property] = new GetterMetadata($this->getClassName(), $property, $method); | |
293 | |
294 $this->addPropertyMetadata($this->getters[$property]); | |
295 } | |
296 | |
297 $constraint->addImplicitGroupName($this->getDefaultGroup()); | |
298 | |
299 $this->getters[$property]->addConstraint($constraint); | |
300 | |
301 return $this; | |
302 } | |
303 | |
304 /** | |
305 * @param string $property | |
306 * @param Constraint[] $constraints | |
307 * | |
308 * @return $this | |
309 */ | |
310 public function addGetterConstraints($property, array $constraints) | |
311 { | |
312 foreach ($constraints as $constraint) { | |
313 $this->addGetterConstraint($property, $constraint); | |
314 } | |
315 | |
316 return $this; | |
317 } | |
318 | |
319 /** | |
320 * @param string $property | |
321 * @param string $method | |
322 * @param Constraint[] $constraints | |
323 * | |
324 * @return $this | |
325 */ | |
326 public function addGetterMethodConstraints($property, $method, array $constraints) | |
327 { | |
328 foreach ($constraints as $constraint) { | |
329 $this->addGetterMethodConstraint($property, $method, $constraint); | |
330 } | |
331 | |
332 return $this; | |
333 } | |
334 | |
335 /** | |
336 * Merges the constraints of the given metadata into this object. | |
337 * | |
338 * @param ClassMetadata $source The source metadata | |
339 */ | |
340 public function mergeConstraints(ClassMetadata $source) | |
341 { | |
342 foreach ($source->getConstraints() as $constraint) { | |
343 $this->addConstraint(clone $constraint); | |
344 } | |
345 | |
346 foreach ($source->getConstrainedProperties() as $property) { | |
347 foreach ($source->getPropertyMetadata($property) as $member) { | |
348 $member = clone $member; | |
349 | |
350 foreach ($member->getConstraints() as $constraint) { | |
351 if (in_array($constraint::DEFAULT_GROUP, $constraint->groups, true)) { | |
352 $member->constraintsByGroup[$this->getDefaultGroup()][] = $constraint; | |
353 } | |
354 | |
355 $constraint->addImplicitGroupName($this->getDefaultGroup()); | |
356 } | |
357 | |
358 $this->addPropertyMetadata($member); | |
359 | |
360 if ($member instanceof MemberMetadata && !$member->isPrivate($this->name)) { | |
361 $property = $member->getPropertyName(); | |
362 | |
363 if ($member instanceof PropertyMetadata && !isset($this->properties[$property])) { | |
364 $this->properties[$property] = $member; | |
365 } elseif ($member instanceof GetterMetadata && !isset($this->getters[$property])) { | |
366 $this->getters[$property] = $member; | |
367 } | |
368 } | |
369 } | |
370 } | |
371 } | |
372 | |
373 /** | |
374 * {@inheritdoc} | |
375 */ | |
376 public function hasPropertyMetadata($property) | |
377 { | |
378 return array_key_exists($property, $this->members); | |
379 } | |
380 | |
381 /** | |
382 * {@inheritdoc} | |
383 */ | |
384 public function getPropertyMetadata($property) | |
385 { | |
386 if (!isset($this->members[$property])) { | |
387 return array(); | |
388 } | |
389 | |
390 return $this->members[$property]; | |
391 } | |
392 | |
393 /** | |
394 * {@inheritdoc} | |
395 */ | |
396 public function getConstrainedProperties() | |
397 { | |
398 return array_keys($this->members); | |
399 } | |
400 | |
401 /** | |
402 * Sets the default group sequence for this class. | |
403 * | |
404 * @param array $groupSequence An array of group names | |
405 * | |
406 * @return $this | |
407 * | |
408 * @throws GroupDefinitionException | |
409 */ | |
410 public function setGroupSequence($groupSequence) | |
411 { | |
412 if ($this->isGroupSequenceProvider()) { | |
413 throw new GroupDefinitionException('Defining a static group sequence is not allowed with a group sequence provider'); | |
414 } | |
415 | |
416 if (is_array($groupSequence)) { | |
417 $groupSequence = new GroupSequence($groupSequence); | |
418 } | |
419 | |
420 if (in_array(Constraint::DEFAULT_GROUP, $groupSequence->groups, true)) { | |
421 throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP)); | |
422 } | |
423 | |
424 if (!in_array($this->getDefaultGroup(), $groupSequence->groups, true)) { | |
425 throw new GroupDefinitionException(sprintf('The group "%s" is missing in the group sequence', $this->getDefaultGroup())); | |
426 } | |
427 | |
428 $this->groupSequence = $groupSequence; | |
429 | |
430 return $this; | |
431 } | |
432 | |
433 /** | |
434 * {@inheritdoc} | |
435 */ | |
436 public function hasGroupSequence() | |
437 { | |
438 return $this->groupSequence && count($this->groupSequence->groups) > 0; | |
439 } | |
440 | |
441 /** | |
442 * {@inheritdoc} | |
443 */ | |
444 public function getGroupSequence() | |
445 { | |
446 return $this->groupSequence; | |
447 } | |
448 | |
449 /** | |
450 * Returns a ReflectionClass instance for this class. | |
451 * | |
452 * @return \ReflectionClass | |
453 */ | |
454 public function getReflectionClass() | |
455 { | |
456 if (!$this->reflClass) { | |
457 $this->reflClass = new \ReflectionClass($this->getClassName()); | |
458 } | |
459 | |
460 return $this->reflClass; | |
461 } | |
462 | |
463 /** | |
464 * Sets whether a group sequence provider should be used. | |
465 * | |
466 * @param bool $active | |
467 * | |
468 * @throws GroupDefinitionException | |
469 */ | |
470 public function setGroupSequenceProvider($active) | |
471 { | |
472 if ($this->hasGroupSequence()) { | |
473 throw new GroupDefinitionException('Defining a group sequence provider is not allowed with a static group sequence'); | |
474 } | |
475 | |
476 if (!$this->getReflectionClass()->implementsInterface('Symfony\Component\Validator\GroupSequenceProviderInterface')) { | |
477 throw new GroupDefinitionException(sprintf('Class "%s" must implement GroupSequenceProviderInterface', $this->name)); | |
478 } | |
479 | |
480 $this->groupSequenceProvider = $active; | |
481 } | |
482 | |
483 /** | |
484 * {@inheritdoc} | |
485 */ | |
486 public function isGroupSequenceProvider() | |
487 { | |
488 return $this->groupSequenceProvider; | |
489 } | |
490 | |
491 /** | |
492 * Class nodes are never cascaded. | |
493 * | |
494 * {@inheritdoc} | |
495 */ | |
496 public function getCascadingStrategy() | |
497 { | |
498 return CascadingStrategy::NONE; | |
499 } | |
500 | |
501 /** | |
502 * Adds a property metadata. | |
503 * | |
504 * @param PropertyMetadataInterface $metadata | |
505 */ | |
506 private function addPropertyMetadata(PropertyMetadataInterface $metadata) | |
507 { | |
508 $property = $metadata->getPropertyName(); | |
509 | |
510 $this->members[$property][] = $metadata; | |
511 } | |
512 } |