]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/form/Symfony/Component/Form/FormBuilder.php
2caefe48bef4cf2385ca442b12fcb0b407aa8644
[github/wallabag/wallabag.git] / vendor / symfony / form / Symfony / Component / Form / FormBuilder.php
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;
13
14 use Symfony\Component\Form\Exception\BadMethodCallException;
15 use Symfony\Component\Form\Exception\InvalidArgumentException;
16 use Symfony\Component\Form\Exception\UnexpectedTypeException;
17 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
18
19 /**
20 * A builder for creating {@link Form} instances.
21 *
22 * @author Bernhard Schussek <bschussek@gmail.com>
23 */
24 class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormBuilderInterface
25 {
26 /**
27 * The children of the form builder.
28 *
29 * @var FormBuilderInterface[]
30 */
31 private $children = array();
32
33 /**
34 * The data of children who haven't been converted to form builders yet.
35 *
36 * @var array
37 */
38 private $unresolvedChildren = array();
39
40 /**
41 * Creates a new form builder.
42 *
43 * @param string $name
44 * @param string $dataClass
45 * @param EventDispatcherInterface $dispatcher
46 * @param FormFactoryInterface $factory
47 * @param array $options
48 */
49 public function __construct($name, $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory, array $options = array())
50 {
51 parent::__construct($name, $dataClass, $dispatcher, $options);
52
53 $this->setFormFactory($factory);
54 }
55
56 /**
57 * {@inheritdoc}
58 */
59 public function add($child, $type = null, array $options = array())
60 {
61 if ($this->locked) {
62 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
63 }
64
65 if ($child instanceof self) {
66 $this->children[$child->getName()] = $child;
67
68 // In case an unresolved child with the same name exists
69 unset($this->unresolvedChildren[$child->getName()]);
70
71 return $this;
72 }
73
74 if (!is_string($child) && !is_int($child)) {
75 throw new UnexpectedTypeException($child, 'string, integer or Symfony\Component\Form\FormBuilder');
76 }
77
78 if (null !== $type && !is_string($type) && !$type instanceof FormTypeInterface) {
79 throw new UnexpectedTypeException($type, 'string or Symfony\Component\Form\FormTypeInterface');
80 }
81
82 // Add to "children" to maintain order
83 $this->children[$child] = null;
84 $this->unresolvedChildren[$child] = array(
85 'type' => $type,
86 'options' => $options,
87 );
88
89 return $this;
90 }
91
92 /**
93 * {@inheritdoc}
94 */
95 public function create($name, $type = null, array $options = array())
96 {
97 if ($this->locked) {
98 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
99 }
100
101 if (null === $type && null === $this->getDataClass()) {
102 $type = 'text';
103 }
104
105 if (null !== $type) {
106 return $this->getFormFactory()->createNamedBuilder($name, $type, null, $options);
107 }
108
109 return $this->getFormFactory()->createBuilderForProperty($this->getDataClass(), $name, null, $options);
110 }
111
112 /**
113 * {@inheritdoc}
114 */
115 public function get($name)
116 {
117 if ($this->locked) {
118 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
119 }
120
121 if (isset($this->unresolvedChildren[$name])) {
122 return $this->resolveChild($name);
123 }
124
125 if (isset($this->children[$name])) {
126 return $this->children[$name];
127 }
128
129 throw new InvalidArgumentException(sprintf('The child with the name "%s" does not exist.', $name));
130 }
131
132 /**
133 * {@inheritdoc}
134 */
135 public function remove($name)
136 {
137 if ($this->locked) {
138 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
139 }
140
141 unset($this->unresolvedChildren[$name]);
142
143 if (array_key_exists($name, $this->children)) {
144 unset($this->children[$name]);
145 }
146
147 return $this;
148 }
149
150 /**
151 * {@inheritdoc}
152 */
153 public function has($name)
154 {
155 if ($this->locked) {
156 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
157 }
158
159 if (isset($this->unresolvedChildren[$name])) {
160 return true;
161 }
162
163 if (isset($this->children[$name])) {
164 return true;
165 }
166
167 return false;
168 }
169
170 /**
171 * {@inheritdoc}
172 */
173 public function all()
174 {
175 if ($this->locked) {
176 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
177 }
178
179 $this->resolveChildren();
180
181 return $this->children;
182 }
183
184 /**
185 * {@inheritdoc}
186 */
187 public function count()
188 {
189 if ($this->locked) {
190 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
191 }
192
193 return count($this->children);
194 }
195
196 /**
197 * {@inheritdoc}
198 */
199 public function getFormConfig()
200 {
201 $config = parent::getFormConfig();
202
203 $config->children = array();
204 $config->unresolvedChildren = array();
205
206 return $config;
207 }
208
209 /**
210 * {@inheritdoc}
211 */
212 public function getForm()
213 {
214 if ($this->locked) {
215 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
216 }
217
218 $this->resolveChildren();
219
220 $form = new Form($this->getFormConfig());
221
222 foreach ($this->children as $child) {
223 // Automatic initialization is only supported on root forms
224 $form->add($child->setAutoInitialize(false)->getForm());
225 }
226
227 if ($this->getAutoInitialize()) {
228 // Automatically initialize the form if it is configured so
229 $form->initialize();
230 }
231
232 return $form;
233 }
234
235 /**
236 * {@inheritdoc}
237 */
238 public function getIterator()
239 {
240 if ($this->locked) {
241 throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
242 }
243
244 return new \ArrayIterator($this->children);
245 }
246
247 /**
248 * Converts an unresolved child into a {@link FormBuilder} instance.
249 *
250 * @param string $name The name of the unresolved child.
251 *
252 * @return FormBuilder The created instance.
253 */
254 private function resolveChild($name)
255 {
256 $info = $this->unresolvedChildren[$name];
257 $child = $this->create($name, $info['type'], $info['options']);
258 $this->children[$name] = $child;
259 unset($this->unresolvedChildren[$name]);
260
261 return $child;
262 }
263
264 /**
265 * Converts all unresolved children into {@link FormBuilder} instances.
266 */
267 private function resolveChildren()
268 {
269 foreach ($this->unresolvedChildren as $name => $info) {
270 $this->children[$name] = $this->create($name, $info['type'], $info['options']);
271 }
272
273 $this->unresolvedChildren = array();
274 }
275 }