diff options
Diffstat (limited to 'vendor/symfony/form/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php')
-rw-r--r-- | vendor/symfony/form/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php new file mode 100644 index 00000000..06d09195 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php | |||
@@ -0,0 +1,250 @@ | |||
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\Form\Extension\Validator\ViolationMapper; | ||
13 | |||
14 | use Symfony\Component\Form\Exception\OutOfBoundsException; | ||
15 | use Symfony\Component\PropertyAccess\PropertyPath; | ||
16 | use Symfony\Component\PropertyAccess\PropertyPathInterface; | ||
17 | |||
18 | /** | ||
19 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
20 | */ | ||
21 | class ViolationPath implements \IteratorAggregate, PropertyPathInterface | ||
22 | { | ||
23 | /** | ||
24 | * @var array | ||
25 | */ | ||
26 | private $elements = array(); | ||
27 | |||
28 | /** | ||
29 | * @var array | ||
30 | */ | ||
31 | private $isIndex = array(); | ||
32 | |||
33 | /** | ||
34 | * @var array | ||
35 | */ | ||
36 | private $mapsForm = array(); | ||
37 | |||
38 | /** | ||
39 | * @var string | ||
40 | */ | ||
41 | private $pathAsString = ''; | ||
42 | |||
43 | /** | ||
44 | * @var integer | ||
45 | */ | ||
46 | private $length = 0; | ||
47 | |||
48 | /** | ||
49 | * Creates a new violation path from a string. | ||
50 | * | ||
51 | * @param string $violationPath The property path of a {@link ConstraintViolation} | ||
52 | * object. | ||
53 | */ | ||
54 | public function __construct($violationPath) | ||
55 | { | ||
56 | $path = new PropertyPath($violationPath); | ||
57 | $elements = $path->getElements(); | ||
58 | $data = false; | ||
59 | |||
60 | for ($i = 0, $l = count($elements); $i < $l; ++$i) { | ||
61 | if (!$data) { | ||
62 | // The element "data" has not yet been passed | ||
63 | if ('children' === $elements[$i] && $path->isProperty($i)) { | ||
64 | // Skip element "children" | ||
65 | ++$i; | ||
66 | |||
67 | // Next element must exist and must be an index | ||
68 | // Otherwise consider this the end of the path | ||
69 | if ($i >= $l || !$path->isIndex($i)) { | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | $this->elements[] = $elements[$i]; | ||
74 | $this->isIndex[] = true; | ||
75 | $this->mapsForm[] = true; | ||
76 | } elseif ('data' === $elements[$i] && $path->isProperty($i)) { | ||
77 | // Skip element "data" | ||
78 | ++$i; | ||
79 | |||
80 | // End of path | ||
81 | if ($i >= $l) { | ||
82 | break; | ||
83 | } | ||
84 | |||
85 | $this->elements[] = $elements[$i]; | ||
86 | $this->isIndex[] = $path->isIndex($i); | ||
87 | $this->mapsForm[] = false; | ||
88 | $data = true; | ||
89 | } else { | ||
90 | // Neither "children" nor "data" property found | ||
91 | // Consider this the end of the path | ||
92 | break; | ||
93 | } | ||
94 | } else { | ||
95 | // Already after the "data" element | ||
96 | // Pick everything as is | ||
97 | $this->elements[] = $elements[$i]; | ||
98 | $this->isIndex[] = $path->isIndex($i); | ||
99 | $this->mapsForm[] = false; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | $this->length = count($this->elements); | ||
104 | |||
105 | $this->buildString(); | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * {@inheritdoc} | ||
110 | */ | ||
111 | public function __toString() | ||
112 | { | ||
113 | return $this->pathAsString; | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * {@inheritdoc} | ||
118 | */ | ||
119 | public function getLength() | ||
120 | { | ||
121 | return $this->length; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * {@inheritdoc} | ||
126 | */ | ||
127 | public function getParent() | ||
128 | { | ||
129 | if ($this->length <= 1) { | ||
130 | return null; | ||
131 | } | ||
132 | |||
133 | $parent = clone $this; | ||
134 | |||
135 | --$parent->length; | ||
136 | array_pop($parent->elements); | ||
137 | array_pop($parent->isIndex); | ||
138 | array_pop($parent->mapsForm); | ||
139 | |||
140 | $parent->buildString(); | ||
141 | |||
142 | return $parent; | ||
143 | } | ||
144 | |||
145 | /** | ||
146 | * {@inheritdoc} | ||
147 | */ | ||
148 | public function getElements() | ||
149 | { | ||
150 | return $this->elements; | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * {@inheritdoc} | ||
155 | */ | ||
156 | public function getElement($index) | ||
157 | { | ||
158 | if (!isset($this->elements[$index])) { | ||
159 | throw new OutOfBoundsException(sprintf('The index %s is not within the violation path', $index)); | ||
160 | } | ||
161 | |||
162 | return $this->elements[$index]; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * {@inheritdoc} | ||
167 | */ | ||
168 | public function isProperty($index) | ||
169 | { | ||
170 | if (!isset($this->isIndex[$index])) { | ||
171 | throw new OutOfBoundsException(sprintf('The index %s is not within the violation path', $index)); | ||
172 | } | ||
173 | |||
174 | return !$this->isIndex[$index]; | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * {@inheritdoc} | ||
179 | */ | ||
180 | public function isIndex($index) | ||
181 | { | ||
182 | if (!isset($this->isIndex[$index])) { | ||
183 | throw new OutOfBoundsException(sprintf('The index %s is not within the violation path', $index)); | ||
184 | } | ||
185 | |||
186 | return $this->isIndex[$index]; | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * Returns whether an element maps directly to a form. | ||
191 | * | ||
192 | * Consider the following violation path: | ||
193 | * | ||
194 | * <code> | ||
195 | * children[address].children[office].data.street | ||
196 | * </code> | ||
197 | * | ||
198 | * In this example, "address" and "office" map to forms, while | ||
199 | * "street does not. | ||
200 | * | ||
201 | * @param integer $index The element index. | ||
202 | * | ||
203 | * @return Boolean Whether the element maps to a form. | ||
204 | * | ||
205 | * @throws OutOfBoundsException If the offset is invalid. | ||
206 | */ | ||
207 | public function mapsForm($index) | ||
208 | { | ||
209 | if (!isset($this->mapsForm[$index])) { | ||
210 | throw new OutOfBoundsException(sprintf('The index %s is not within the violation path', $index)); | ||
211 | } | ||
212 | |||
213 | return $this->mapsForm[$index]; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * Returns a new iterator for this path | ||
218 | * | ||
219 | * @return ViolationPathIterator | ||
220 | */ | ||
221 | public function getIterator() | ||
222 | { | ||
223 | return new ViolationPathIterator($this); | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * Builds the string representation from the elements. | ||
228 | */ | ||
229 | private function buildString() | ||
230 | { | ||
231 | $this->pathAsString = ''; | ||
232 | $data = false; | ||
233 | |||
234 | foreach ($this->elements as $index => $element) { | ||
235 | if ($this->mapsForm[$index]) { | ||
236 | $this->pathAsString .= ".children[$element]"; | ||
237 | } elseif (!$data) { | ||
238 | $this->pathAsString .= '.data'.($this->isIndex[$index] ? "[$element]" : ".$element"); | ||
239 | $data = true; | ||
240 | } else { | ||
241 | $this->pathAsString .= $this->isIndex[$index] ? "[$element]" : ".$element"; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | if ('' !== $this->pathAsString) { | ||
246 | // remove leading dot | ||
247 | $this->pathAsString = substr($this->pathAsString, 1); | ||
248 | } | ||
249 | } | ||
250 | } | ||