]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/form/Symfony/Component/Form/ResolvedFormType.php
twig implementation
[github/wallabag/wallabag.git] / vendor / symfony / form / Symfony / Component / Form / ResolvedFormType.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\InvalidArgumentException;
15 use Symfony\Component\Form\Exception\UnexpectedTypeException;
16 use Symfony\Component\EventDispatcher\EventDispatcher;
17 use Symfony\Component\OptionsResolver\OptionsResolver;
18
19 /**
20 * A wrapper for a form type and its extensions.
21 *
22 * @author Bernhard Schussek <bschussek@gmail.com>
23 */
24 class ResolvedFormType implements ResolvedFormTypeInterface
25 {
26 /**
27 * @var FormTypeInterface
28 */
29 private $innerType;
30
31 /**
32 * @var array
33 */
34 private $typeExtensions;
35
36 /**
37 * @var ResolvedFormTypeInterface
38 */
39 private $parent;
40
41 /**
42 * @var OptionsResolver
43 */
44 private $optionsResolver;
45
46 public function __construct(FormTypeInterface $innerType, array $typeExtensions = array(), ResolvedFormTypeInterface $parent = null)
47 {
48 if (!preg_match('/^[a-z0-9_]*$/i', $innerType->getName())) {
49 throw new InvalidArgumentException(sprintf(
50 'The "%s" form type name ("%s") is not valid. Names must only contain letters, numbers, and "_".',
51 get_class($innerType),
52 $innerType->getName()
53 ));
54 }
55
56 foreach ($typeExtensions as $extension) {
57 if (!$extension instanceof FormTypeExtensionInterface) {
58 throw new UnexpectedTypeException($extension, 'Symfony\Component\Form\FormTypeExtensionInterface');
59 }
60 }
61
62 $this->innerType = $innerType;
63 $this->typeExtensions = $typeExtensions;
64 $this->parent = $parent;
65 }
66
67 /**
68 * {@inheritdoc}
69 */
70 public function getName()
71 {
72 return $this->innerType->getName();
73 }
74
75 /**
76 * {@inheritdoc}
77 */
78 public function getParent()
79 {
80 return $this->parent;
81 }
82
83 /**
84 * {@inheritdoc}
85 */
86 public function getInnerType()
87 {
88 return $this->innerType;
89 }
90
91 /**
92 * {@inheritdoc}
93 */
94 public function getTypeExtensions()
95 {
96 // BC
97 if ($this->innerType instanceof AbstractType) {
98 return $this->innerType->getExtensions();
99 }
100
101 return $this->typeExtensions;
102 }
103
104 /**
105 * {@inheritdoc}
106 */
107 public function createBuilder(FormFactoryInterface $factory, $name, array $options = array())
108 {
109 $options = $this->getOptionsResolver()->resolve($options);
110
111 // Should be decoupled from the specific option at some point
112 $dataClass = isset($options['data_class']) ? $options['data_class'] : null;
113
114 $builder = $this->newBuilder($name, $dataClass, $factory, $options);
115 $builder->setType($this);
116
117 $this->buildForm($builder, $options);
118
119 return $builder;
120 }
121
122 /**
123 * {@inheritdoc}
124 */
125 public function createView(FormInterface $form, FormView $parent = null)
126 {
127 $options = $form->getConfig()->getOptions();
128
129 $view = $this->newView($parent);
130
131 $this->buildView($view, $form, $options);
132
133 foreach ($form as $name => $child) {
134 /* @var FormInterface $child */
135 $view->children[$name] = $child->createView($view);
136 }
137
138 $this->finishView($view, $form, $options);
139
140 return $view;
141 }
142
143 /**
144 * Configures a form builder for the type hierarchy.
145 *
146 * This method is protected in order to allow implementing classes
147 * to change or call it in re-implementations of {@link createBuilder()}.
148 *
149 * @param FormBuilderInterface $builder The builder to configure.
150 * @param array $options The options used for the configuration.
151 */
152 public function buildForm(FormBuilderInterface $builder, array $options)
153 {
154 if (null !== $this->parent) {
155 $this->parent->buildForm($builder, $options);
156 }
157
158 $this->innerType->buildForm($builder, $options);
159
160 foreach ($this->typeExtensions as $extension) {
161 /* @var FormTypeExtensionInterface $extension */
162 $extension->buildForm($builder, $options);
163 }
164 }
165
166 /**
167 * Configures a form view for the type hierarchy.
168 *
169 * This method is protected in order to allow implementing classes
170 * to change or call it in re-implementations of {@link createView()}.
171 *
172 * It is called before the children of the view are built.
173 *
174 * @param FormView $view The form view to configure.
175 * @param FormInterface $form The form corresponding to the view.
176 * @param array $options The options used for the configuration.
177 */
178 public function buildView(FormView $view, FormInterface $form, array $options)
179 {
180 if (null !== $this->parent) {
181 $this->parent->buildView($view, $form, $options);
182 }
183
184 $this->innerType->buildView($view, $form, $options);
185
186 foreach ($this->typeExtensions as $extension) {
187 /* @var FormTypeExtensionInterface $extension */
188 $extension->buildView($view, $form, $options);
189 }
190 }
191
192 /**
193 * Finishes a form view for the type hierarchy.
194 *
195 * This method is protected in order to allow implementing classes
196 * to change or call it in re-implementations of {@link createView()}.
197 *
198 * It is called after the children of the view have been built.
199 *
200 * @param FormView $view The form view to configure.
201 * @param FormInterface $form The form corresponding to the view.
202 * @param array $options The options used for the configuration.
203 */
204 public function finishView(FormView $view, FormInterface $form, array $options)
205 {
206 if (null !== $this->parent) {
207 $this->parent->finishView($view, $form, $options);
208 }
209
210 $this->innerType->finishView($view, $form, $options);
211
212 foreach ($this->typeExtensions as $extension) {
213 /* @var FormTypeExtensionInterface $extension */
214 $extension->finishView($view, $form, $options);
215 }
216 }
217
218 /**
219 * Returns the configured options resolver used for this type.
220 *
221 * This method is protected in order to allow implementing classes
222 * to change or call it in re-implementations of {@link createBuilder()}.
223 *
224 * @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
225 */
226 public function getOptionsResolver()
227 {
228 if (null === $this->optionsResolver) {
229 if (null !== $this->parent) {
230 $this->optionsResolver = clone $this->parent->getOptionsResolver();
231 } else {
232 $this->optionsResolver = new OptionsResolver();
233 }
234
235 $this->innerType->setDefaultOptions($this->optionsResolver);
236
237 foreach ($this->typeExtensions as $extension) {
238 /* @var FormTypeExtensionInterface $extension */
239 $extension->setDefaultOptions($this->optionsResolver);
240 }
241 }
242
243 return $this->optionsResolver;
244 }
245
246 /**
247 * Creates a new builder instance.
248 *
249 * Override this method if you want to customize the builder class.
250 *
251 * @param string $name The name of the builder.
252 * @param string $dataClass The data class.
253 * @param FormFactoryInterface $factory The current form factory.
254 * @param array $options The builder options.
255 *
256 * @return FormBuilderInterface The new builder instance.
257 */
258 protected function newBuilder($name, $dataClass, FormFactoryInterface $factory, array $options)
259 {
260 if ($this->innerType instanceof ButtonTypeInterface) {
261 return new ButtonBuilder($name, $options);
262 }
263
264 if ($this->innerType instanceof SubmitButtonTypeInterface) {
265 return new SubmitButtonBuilder($name, $options);
266 }
267
268 return new FormBuilder($name, $dataClass, new EventDispatcher(), $factory, $options);
269 }
270
271 /**
272 * Creates a new view instance.
273 *
274 * Override this method if you want to customize the view class.
275 *
276 * @param FormView|null $parent The parent view, if available.
277 *
278 * @return FormView A new view instance.
279 */
280 protected function newView(FormView $parent = null)
281 {
282 return new FormView($parent);
283 }
284 }