J'ai lu les exemples, et j'ai fait de mon mieux pour chercher dans la doc.
Malheureusement, je n'arrive pas à faire d'itérateur récursif "proprement".
Par proprement, j'entends en exploitant au maximum les fonctionnalitées de SPL, au lieu de simplement implémenter Iterator avec des fonctions complexes et plein de variables.
Je suis encore un peu confus quand à l'implémentation de l'iterateur, et j'hésite donc entre la façon qui est dans le docblock de classe, et celle qui est décrite dans le docblock de la méthode setIteratorOption().
La première solution est plus naturelle pour "usiner" un itérateur externe, quand à la seconde: elle est plus naturelle pour implémenter Iterator avec des options dans la classe (ce à quoi je me résigne petit-à-petit, en fait).
Voici la classe:
Voici le test:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181 <?php /** * File containing class daFormGroupElement. * * @uses daFormElement * @package Form * @version //autogen// * @copyright Copyright (C) 2008 eZ Systems As. All rights reserved. * @author James * @license http://ez.no/licenses/new_bsd New BSD License */ /** * This class allows to wrap several elements into one element. * * <code> * <?php * // instanciate a group * $group = new daFormGroupElement( $name, $label, $description, $required ); * // add an element * $group->addElement( new daFormTextElement( 'nick', 'your nickname', 'your nickname is useful for others to recognize you', true ) ); * // get an element * $nick = $group->getElement( 'nick' ); * // remove an element * $group->removeElement( $nick ); * * foreach( $group->getIterator() as $element ) * { * // loops over all elements of that group * } * * foreach( $group->getIterator( true ) as $element ) * { * // loops over all elements of that group expect group elements * } * * foreach( $group->getRecursiveIterator() as $element ) * { * // loops over all elements of that group and all sub-groups * } * * foreach( $group->getRecursiveIterator( true ) as $element ) * { * // loops over all elements of that group and all sub-groups * // without returning any group element * } * ?> * </code> * * @uses daFormElement * @package Form * @version //autogen// */ class daFormGroupElement extends daFormElement implements RecursiveIterator, Countable { /** * List of elements. * * @var array(name=>element) */ protected $elements = array(); protected $iteratorOptions = array( 'hideGroups' => false, 'recursive' => false, ); private $currentElement = null; private $currentGroup = null; public function __construct( $name, $label, $description, $required = true ) { parent::__construct( $name, $label, $description, $required ); $this->addElement( $this ); } /** * Adds an element in the group. * * @param daFormElement $element The element to add, the method will return it. * @return daFormElement The passed element. */ public function addElement( daFormElement $element ) { $this->elements[$element->name] = $element; return $element; } /** * Removes an element from the group. * * @param daFormElement $element * @return void */ public function removeElement( daFormElement $element ) { unset( $this->elements[$element->name] ); } /** * Returns an element from the group. * * @param string $name * @return daFormElement */ public function getElement( $name ) { return $this->elements[$name]; } /** * Sets any of the following options: hideGroups, recursive. * * @param string $option Name of the option to set. * @param bool $value Value of the option to set. * @return daFormGroupElement */ public function setIteratorOption( $option, $value ) { if ( !is_string( $option ) ) { throw new ezcBaseValueException( 'option', $option, 'strings', 'argument' ); } if ( !in_array( $option, $this->iteratorOptions ) ) { throw new ezcBaseValueException( 'option', $option, 'any of the following: ' . join( ', ', $this->iteratorOptions ), 'argument' ); } if ( !is_bool( $value ) ) { throw new ezcBaseValueException( 'value', $value, 'bools', 'argument' ); } $this->iteratorOptions[$option] = $value; } /** * Returns the number of elements in the group. * * @return int Number of elements in the group. */ public function count() { return count( $this->elements ) - 1; } public function next() { next( $this->elements ); } public function current() { return current( $this->elements ); } public function rewind() { reset( $this->elements ); } public function valid() { return !is_null( key( $this->elements ) ); } public function key() { return key( $this->elements ); } public function hasChildren() { $current = $this->current(); return $current && $current instanceof daFormGroupElement && count( $current ); } public function getChildren() { return $this->current(); } } ?>
Voici le résultat du test:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 <?php class daFormTestGroupElement extends daFormTestCase { static public function suite() { return new PHPUnit_Framework_TestSuite( 'daFormTestGroupElement' ); } // functionnal tests public function testElementContainerWithCount() { $g = new daFormGroupElement( 'testGroup', 'labelGroup', 'descriptionGroup', true ); $el = $g->addElement( new daFormTestElementMock( 'testElement', 'labelElement', 'descriptionElement', true ) ); $el2 = $g->addElement( new daFormTestElementMock( 'testElement2', 'labelElement2', 'descriptionElement2', true ) ); $this->assertEquals( 2, count( $g ) ); $g->removeElement( $el ); $this->assertEquals( 1, count( $g ) ); $this->assertEquals( $el2, $g->getElement( 'testElement2' ) ); } public function testRecursiveIterator() { $root = self::getForm(); $i = 0; foreach( $root as $name => $element ) { switch( $i ) { case 0: $this->assertEquals( 'widget', $name ); $this->assertEquals( $root, $element ); break; case 1: $this->assertEquals( 'name', $name ); $this->assertEquals( $root->getElement( $name ), $element ); break; case 2: $this->assertEquals( 'address', $name ); $address = $this->assertEquals( $root->getElement( $name ), $element ); break; case 3: $this->assertEquals( 'street', $name ); $this->assertEquals( $address->getElement( $name ), $element ); break; case 4: $this->assertEquals( 'city_group', $name ); $this->assertEquals( $root->getElement( $name ), $element ); break; case 5: $this->assertEquals( 'country', $name ); $this->assertEquals( $root->getElement( $name ), $element ); break; case 6: $this->assertEquals( 'zip', $name ); $this->assertEquals( $root->getElement( $name ), $element ); break; case 7: $this->assertEquals( 'city', $name ); $this->assertEquals( $root->getElement( $name ), $element ); break; case 8: $this->assertEquals( 'fav_lang', $name ); $this->assertEquals( $root->getElement( $name ), $element ); break; } $i++; } $this->assertEquals( 8, $i ); } static public function getForm() { $form = new daFormGroupElement( 'widget', 'The widget of your dreams', 'Please fill this form and let us know about the best widget that you could think of' ); $form->addElement( new daFormTextElement( 'name', 'Your name', 'Please type your name.' ) ); $address = $form->addElement( new daFormGroupElement( 'address', 'Your Address', 'We need your address to contact you' ) ); $address->addElement( new daFormTextElement( 'street', 'Street name', 'The name of your street' ) ); $city = $address->addElement( new daFormGroupElement( 'city_group', 'Your city', 'Maybe we can figure your city name with your country and zip' ) ); $city->addElement( new daFormTextElement( 'country', 'Country', 'Your country' ) ); $city->addElement( new daFormTextElement( 'zip', 'Zip', 'Your zipcode' ) ); $address->addElement( new daFormTextElement( 'city', 'City', 'Your city name is where you live', false ) ); $form->addElement( new daFormTextElement( 'fav_lang', 'Your favourite language', 'Please type "PHP" in this field or be banned' ) ); return $form; } } ?>
On remarque que l'itération n'est pas récursive du tout, et c'est la raison de l'échec du test.There was 1 failure:
1) testRecursiveIterator(daFormTestGroupElement)
Failed asserting that two strings are equal.
expected string <street>
difference <xxxxxx??>
got string <fav_lang>
/pd/sources/dac2/trunk/Form/tests/elements/group.php:43
Notez que les autres classes impliquées sont testées et documentées.
Débutant en OO, en developpement conduit par tests fonctionnels, en SPL Iterators ainsi qu'en documentation, j'éspère que je n'ai pas écrit de bêtises et que vous avez de quoi comprendre et résoudre mon problême dans ce message![]()







Répondre avec citation
Partager