16
16
use Symfony \Component \Validator \Exception \NoSuchMetadataException ;
17
17
use Symfony \Component \Validator \Mapping \CascadingStrategy ;
18
18
use Symfony \Component \Validator \Mapping \ClassMetadataInterface ;
19
+ use Symfony \Component \Validator \Mapping \CollectionMetadata ;
19
20
use Symfony \Component \Validator \Mapping \TraversalStrategy ;
20
21
use Symfony \Component \Validator \MetadataFactoryInterface ;
21
22
use Symfony \Component \Validator \Node \ClassNode ;
23
+ use Symfony \Component \Validator \Node \CollectionNode ;
22
24
use Symfony \Component \Validator \Node \Node ;
23
25
use Symfony \Component \Validator \Node \PropertyNode ;
24
26
use Symfony \Component \Validator \NodeVisitor \NodeVisitorInterface ;
@@ -84,6 +86,8 @@ public function traverse(array $nodes, ExecutionContextInterface $context)
84
86
85
87
if ($ node instanceof ClassNode) {
86
88
$ this ->traverseClassNode ($ node , $ traversal );
89
+ } elseif ($ node instanceof CollectionNode) {
90
+ $ this ->traverseCollectionNode ($ node , $ traversal );
87
91
} else {
88
92
$ this ->traverseNode ($ node , $ traversal );
89
93
}
@@ -145,13 +149,12 @@ private function traverseNode(Node $node, Traversal $traversal)
145
149
// Arrays are always traversed, independent of the specified
146
150
// traversal strategy
147
151
// (BC with Symfony < 2.5)
148
- $ this -> cascadeEachObjectIn (
152
+ $ traversal -> nodeQueue -> enqueue ( new CollectionNode (
149
153
$ node ->value ,
154
+ new CollectionMetadata ($ traversalStrategy ),
150
155
$ node ->propertyPath ,
151
- $ cascadedGroups ,
152
- $ traversalStrategy ,
153
- $ traversal
154
- );
156
+ $ cascadedGroups
157
+ ));
155
158
156
159
return ;
157
160
}
@@ -188,13 +191,13 @@ private function traverseNode(Node $node, Traversal $traversal)
188
191
));
189
192
}
190
193
191
- $ this -> cascadeEachObjectIn (
194
+ $ traversal -> nodeQueue -> enqueue ( new CollectionNode (
192
195
$ node ->value ,
196
+ new CollectionMetadata ($ traversalStrategy ),
193
197
$ node ->propertyPath ,
194
- $ cascadedGroups ,
195
- $ traversalStrategy ,
196
- $ traversal
197
- );
198
+ $ node ->groups ,
199
+ $ node ->cascadedGroups
200
+ ));
198
201
}
199
202
200
203
private function traverseClassNode (ClassNode $ node , Traversal $ traversal , $ traversalStrategy = TraversalStrategy::IMPLICIT )
@@ -252,54 +255,23 @@ private function traverseClassNode(ClassNode $node, Traversal $traversal, $trave
252
255
));
253
256
}
254
257
255
- $ this -> cascadeEachObjectIn (
258
+ $ traversal -> nodeQueue -> enqueue ( new CollectionNode (
256
259
$ node ->value ,
260
+ new CollectionMetadata ($ traversalStrategy ),
257
261
$ node ->propertyPath ,
258
262
$ node ->groups ,
259
- $ traversalStrategy ,
260
- $ traversal
261
- );
263
+ $ node ->cascadedGroups
264
+ ));
262
265
}
263
266
264
- private function cascadeObject ( $ object , $ propertyPath , array $ groups , $ traversalStrategy , Traversal $ traversal )
267
+ private function traverseCollectionNode ( CollectionNode $ node , Traversal $ traversal )
265
268
{
266
- try {
267
- $ classMetadata = $ this ->metadataFactory ->getMetadataFor ($ object );
268
-
269
- if (!$ classMetadata instanceof ClassMetadataInterface) {
270
- // error
271
- }
272
-
273
- $ traversal ->nodeQueue ->enqueue (new ClassNode (
274
- $ object ,
275
- $ classMetadata ,
276
- $ propertyPath ,
277
- $ groups
278
- ));
279
- } catch (NoSuchMetadataException $ e ) {
280
- // Rethrow if the TRAVERSE bit is not set
281
- if (!($ traversalStrategy & TraversalStrategy::TRAVERSE )) {
282
- throw $ e ;
283
- }
284
-
285
- // Rethrow if the object does not implement Traversable
286
- if (!$ object instanceof \Traversable) {
287
- throw $ e ;
288
- }
289
-
290
- // In that case, iterate the object and cascade each entry
291
- $ this ->cascadeEachObjectIn (
292
- $ object ,
293
- $ propertyPath ,
294
- $ groups ,
295
- $ traversalStrategy ,
296
- $ traversal
297
- );
269
+ if (false === $ this ->visit ($ node , $ traversal ->context )) {
270
+ return ;
298
271
}
299
- }
300
272
301
- private function cascadeEachObjectIn ( $ collection , $ propertyPath , array $ groups , $ traversalStrategy, Traversal $ traversal )
302
- {
273
+ $ traversalStrategy = $ node -> metadata -> getTraversalStrategy ();
274
+
303
275
if ($ traversalStrategy & TraversalStrategy::RECURSIVE ) {
304
276
// Try to traverse nested objects, but ignore if they do not
305
277
// implement Traversable
@@ -311,18 +283,17 @@ private function cascadeEachObjectIn($collection, $propertyPath, array $groups,
311
283
$ traversalStrategy = TraversalStrategy::IMPLICIT ;
312
284
}
313
285
314
- foreach ($ collection as $ key => $ value ) {
286
+ foreach ($ node -> value as $ key => $ value ) {
315
287
if (is_array ($ value )) {
316
288
// Arrays are always cascaded, independent of the specified
317
289
// traversal strategy
318
290
// (BC with Symfony < 2.5)
319
- $ this -> cascadeEachObjectIn (
291
+ $ traversal -> nodeQueue -> enqueue ( new CollectionNode (
320
292
$ value ,
321
- $ propertyPath .'[ ' .$ key .'] ' ,
322
- $ groups ,
323
- $ traversalStrategy ,
324
- $ traversal
325
- );
293
+ new CollectionMetadata ($ traversalStrategy ),
294
+ $ node ->propertyPath .'[ ' .$ key .'] ' ,
295
+ $ node ->groups
296
+ ));
326
297
327
298
continue ;
328
299
}
@@ -332,12 +303,47 @@ private function cascadeEachObjectIn($collection, $propertyPath, array $groups,
332
303
if (is_object ($ value )) {
333
304
$ this ->cascadeObject (
334
305
$ value ,
335
- $ propertyPath .'[ ' .$ key .'] ' ,
336
- $ groups ,
306
+ $ node -> propertyPath .'[ ' .$ key .'] ' ,
307
+ $ node -> groups ,
337
308
$ traversalStrategy ,
338
309
$ traversal
339
310
);
340
311
}
341
312
}
342
313
}
314
+
315
+ private function cascadeObject ($ object , $ propertyPath , array $ groups , $ traversalStrategy , Traversal $ traversal )
316
+ {
317
+ try {
318
+ $ classMetadata = $ this ->metadataFactory ->getMetadataFor ($ object );
319
+
320
+ if (!$ classMetadata instanceof ClassMetadataInterface) {
321
+ // error
322
+ }
323
+
324
+ $ traversal ->nodeQueue ->enqueue (new ClassNode (
325
+ $ object ,
326
+ $ classMetadata ,
327
+ $ propertyPath ,
328
+ $ groups
329
+ ));
330
+ } catch (NoSuchMetadataException $ e ) {
331
+ // Rethrow if the TRAVERSE bit is not set
332
+ if (!($ traversalStrategy & TraversalStrategy::TRAVERSE )) {
333
+ throw $ e ;
334
+ }
335
+
336
+ // Rethrow if the object does not implement Traversable
337
+ if (!$ object instanceof \Traversable) {
338
+ throw $ e ;
339
+ }
340
+
341
+ $ traversal ->nodeQueue ->enqueue (new CollectionNode (
342
+ $ object ,
343
+ new CollectionMetadata ($ traversalStrategy ),
344
+ $ propertyPath ,
345
<
4885
span class="diff-text-marker">+ $ groups
346
+ ));
347
+ }
348
+ }
343
349
}
0 commit comments