1
1
Traverse
2
2
========
3
3
4
- Objects do not validate nested objects by default unless explicitly using
5
- this constraint .
6
- If only specific nested objects should be validated by cascade, consider
7
- using the :doc: ` /reference/constraints/Valid ` instead .
4
+ Objects properties are only validated if they are accessible, either by being
5
+ public or having public accessor methods (e.g a public getter) .
6
+ If your object needs to be traversed to validate its data, you can use this
7
+ constraint .
8
8
9
9
+----------------+-------------------------------------------------------------------------------------+
10
10
| Applies to | :ref: `class <validation-class-target >` |
@@ -17,17 +17,14 @@ using the :doc:`/reference/constraints/Valid` instead.
17
17
Basic Usage
18
18
-----------
19
19
20
- In the following example, create three classes ``Book ``, ``Author `` and
21
- ``Editor `` that all have constraints on their properties. Furthermore,
22
- ``Book `` stores an ``Author `` and an ``Editor `` instance that must be
23
- valid too. Instead of adding the ``Valid `` constraint to both fields,
24
- configure the ``Traverse `` constraint on the ``Book `` class.
20
+ In the following example, create two classes ``BookCollection `` and ``Book ``
21
+ that all have constraints on their properties.
25
22
26
23
.. configuration-block ::
27
24
28
25
.. code-block :: php-annotations
29
26
30
- // src/AppBundle/Entity/Book .php
27
+ // src/AppBundle/Entity/BookCollection .php
31
28
namespace AppBundle\Entity;
32
29
33
30
use Doctrine\ORM\Mapping as ORM;
@@ -37,31 +34,66 @@ configure the ``Traverse`` constraint on the ``Book`` class.
37
34
* @ORM\Entity
38
35
* @Assert\Traverse
39
36
*/
40
- class Book
37
+ class BookCollection implements \IteratorAggregate
41
38
{
42
39
/**
43
- * @var Author
40
+ * @var string
41
+ *
42
+ * @ORM\Column
44
43
*
45
- * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Author")
44
+ * @Assert\NotBlank
46
45
*/
47
- protected $author ;
46
+ protected $name = '' ;
48
47
49
48
/**
50
- * @var Editor
49
+ * @var Book[]
51
50
*
52
- * @ORM\ManyToOne (targetEntity="AppBundle\Entity\Editor ")
51
+ * @ORM\ManyToMany (targetEntity="AppBundle\Entity\Book ")
53
52
*/
54
- protected $editor ;
53
+ protected $books ;
55
54
56
- // ...
55
+ // some other properties
56
+
57
+ public function __construct()
58
+ {
59
+ $this->books = new ArrayCollection();
60
+ }
61
+
62
+ // ... setter for name, adder and remover for books
63
+
64
+ // the name can be validated by calling the getter
65
+ public function getName(): string
66
+ {
67
+ return $this->name;
68
+ }
69
+
70
+ /**
71
+ * @return Book[]|\Generator The books for a given author
72
+ */
73
+ public function getBooksForAuthor(Author $author): iterable
74
+ {
75
+ foreach ($this->books as $book) {
76
+ if ($book->isAuthoredBy($author)) {
77
+ yield $book;
78
+ }
79
+ }
80
+ }
81
+
82
+ // neither the method above nor any other specific getter
83
+ // could be used to validated all nested books
84
+ // this object needs to be traversed to call the iterator
85
+ public function getIterator()
86
+ {
87
+ return $this->books->getIterator();
88
+ }
57
89
}
58
90
59
91
.. code-block :: yaml
60
92
61
93
# src/AppBundle/Resources/config/validation.yml
62
- AppBundle\Entity\Book :
94
+ AppBundle\Entity\BookCollection :
63
95
constraints :
64
- - Symfony\Component\Validator\Constraints\ Traverse : ~
96
+ - Traverse : ~
65
97
66
98
.. code-block :: xml
67
99
@@ -71,8 +103,8 @@ configure the ``Traverse`` constraint on the ``Book`` class.
71
103
xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
72
104
xsi : schemaLocation =" http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd" >
73
105
74
- <class name =" AppBundle\Entity\Book " >
75
- <constraint name =" Symfony\Component\Validator\Constraints\ Traverse" />
106
+ <class name =" AppBundle\Entity\BookCollection " >
107
+ <constraint name =" Traverse" />
76
108
</class >
77
109
</constraint-mapping >
78
110
@@ -84,15 +116,23 @@ configure the ``Traverse`` constraint on the ``Book`` class.
84
116
use Symfony\Component\Validator\Constraints as Assert;
85
117
use Symfony\Component\Validator\Mapping\ClassMetadata;
86
118
87
- class Book
119
+ class BookCollection
88
120
{
121
+ // ...
122
+
89
123
public static function loadValidatorMetadata(ClassMetadata $metadata)
90
124
{
91
125
$metadata->addConstraint(new Assert\Traverse());
92
126
}
93
127
}
94
128
129
+ If a public getter exists to return the inner books collection like
130
+ ``getBooks(): Collection ``, the :doc: `/reference/constraints/Valid ` constraint
131
+ can be used on the ``$books `` property instead.
132
+
95
133
Options
96
134
-------
97
135
136
+ The ``groups `` option is not available for this constraint.
137
+
98
138
.. include :: /reference/constraints/_payload-option.rst.inc
0 commit comments