Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/validator/Constraints/Composite.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 129ea1e6d783 |
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\Constraints; | |
13 | |
14 use Symfony\Component\Validator\Constraint; | |
15 use Symfony\Component\Validator\Exception\ConstraintDefinitionException; | |
16 | |
17 /** | |
18 * A constraint that is composed of other constraints. | |
19 * | |
20 * You should never use the nested constraint instances anywhere else, because | |
21 * their groups are adapted when passed to the constructor of this class. | |
22 * | |
23 * If you want to create your own composite constraint, extend this class and | |
24 * let {@link getCompositeOption()} return the name of the property which | |
25 * contains the nested constraints. | |
26 * | |
27 * @author Bernhard Schussek <bschussek@gmail.com> | |
28 */ | |
29 abstract class Composite extends Constraint | |
30 { | |
31 /** | |
32 * {@inheritdoc} | |
33 * | |
34 * The groups of the composite and its nested constraints are made | |
35 * consistent using the following strategy: | |
36 * | |
37 * - If groups are passed explicitly to the composite constraint, but | |
38 * not to the nested constraints, the options of the composite | |
39 * constraint are copied to the nested constraints; | |
40 * | |
41 * - If groups are passed explicitly to the nested constraints, but not | |
42 * to the composite constraint, the groups of all nested constraints | |
43 * are merged and used as groups for the composite constraint; | |
44 * | |
45 * - If groups are passed explicitly to both the composite and its nested | |
46 * constraints, the groups of the nested constraints must be a subset | |
47 * of the groups of the composite constraint. If not, a | |
48 * {@link ConstraintDefinitionException} is thrown. | |
49 * | |
50 * All this is done in the constructor, because constraints can then be | |
51 * cached. When constraints are loaded from the cache, no more group | |
52 * checks need to be done. | |
53 */ | |
54 public function __construct($options = null) | |
55 { | |
56 parent::__construct($options); | |
57 | |
58 $this->initializeNestedConstraints(); | |
59 | |
60 /* @var Constraint[] $nestedConstraints */ | |
61 $compositeOption = $this->getCompositeOption(); | |
62 $nestedConstraints = $this->$compositeOption; | |
63 | |
64 if (!is_array($nestedConstraints)) { | |
65 $nestedConstraints = array($nestedConstraints); | |
66 } | |
67 | |
68 foreach ($nestedConstraints as $constraint) { | |
69 if (!$constraint instanceof Constraint) { | |
70 if (is_object($constraint)) { | |
71 $constraint = get_class($constraint); | |
72 } | |
73 | |
74 throw new ConstraintDefinitionException(sprintf('The value %s is not an instance of Constraint in constraint %s', $constraint, get_class($this))); | |
75 } | |
76 | |
77 if ($constraint instanceof Valid) { | |
78 throw new ConstraintDefinitionException(sprintf('The constraint Valid cannot be nested inside constraint %s. You can only declare the Valid constraint directly on a field or method.', get_class($this))); | |
79 } | |
80 } | |
81 | |
82 if (!property_exists($this, 'groups')) { | |
83 $mergedGroups = array(); | |
84 | |
85 foreach ($nestedConstraints as $constraint) { | |
86 foreach ($constraint->groups as $group) { | |
87 $mergedGroups[$group] = true; | |
88 } | |
89 } | |
90 | |
91 $this->groups = array_keys($mergedGroups); | |
92 $this->$compositeOption = $nestedConstraints; | |
93 | |
94 return; | |
95 } | |
96 | |
97 foreach ($nestedConstraints as $constraint) { | |
98 if (property_exists($constraint, 'groups')) { | |
99 $excessGroups = array_diff($constraint->groups, $this->groups); | |
100 | |
101 if (count($excessGroups) > 0) { | |
102 throw new ConstraintDefinitionException(sprintf( | |
103 'The group(s) "%s" passed to the constraint %s '. | |
104 'should also be passed to its containing constraint %s', | |
105 implode('", "', $excessGroups), | |
106 get_class($constraint), | |
107 get_class($this) | |
108 )); | |
109 } | |
110 } else { | |
111 $constraint->groups = $this->groups; | |
112 } | |
113 } | |
114 | |
115 $this->$compositeOption = $nestedConstraints; | |
116 } | |
117 | |
118 /** | |
119 * {@inheritdoc} | |
120 * | |
121 * Implicit group names are forwarded to nested constraints. | |
122 * | |
123 * @param string $group | |
124 */ | |
125 public function addImplicitGroupName($group) | |
126 { | |
127 parent::addImplicitGroupName($group); | |
128 | |
129 /** @var Constraint[] $nestedConstraints */ | |
130 $nestedConstraints = $this->{$this->getCompositeOption()}; | |
131 | |
132 foreach ($nestedConstraints as $constraint) { | |
133 $constraint->addImplicitGroupName($group); | |
134 } | |
135 } | |
136 | |
137 /** | |
138 * Returns the name of the property that contains the nested constraints. | |
139 * | |
140 * @return string The property name | |
141 */ | |
142 abstract protected function getCompositeOption(); | |
143 | |
144 /** | |
145 * Initializes the nested constraints. | |
146 * | |
147 * This method can be overwritten in subclasses to clean up the nested | |
148 * constraints passed to the constructor. | |
149 * | |
150 * @see Collection::initializeNestedConstraints() | |
151 */ | |
152 protected function initializeNestedConstraints() | |
153 { | |
154 } | |
155 } |