8000 [Form] Decoupled methods of ResolvedFormType so that they can be over… · symfony/symfony@56d78ed · GitHub
[go: up one dir, main page]

Skip to content

Commit 56d78ed

Browse files
committed
[Form] Decoupled methods of ResolvedFormType so that they can be overridden individually by decorators
1 parent a994a5d commit 56d78ed

8 files changed

+422
-181
lines changed

src/Symfony/Component/Form/Button.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,16 @@ public function createView(FormView $parent = null)
412412
$parent = $this->parent->createView();
413413
}
414414

415-
return $this->config->getType()->createView($this, $parent);
415+
416+
$type = $this->config->getType();
417+
$options = $this->config->getOptions();
418+
419+
$view = $type->createView($this, $parent);
420+
421+
$type->buildView($view, $this, $options);
422+
$type->finishView($view, $this, $options);
423+
424+
return $view;
416425
}
417426

418427
/**

src/Symfony/Component/Form/Form.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,23 @@ public function createView(FormView $parent = null)
969969
$parent = $this->parent->createView();
970970
}
971971

972-
return $this->config->getType()->createView($this, $parent);
972+
$type = $this->config->getType();
973+
$options = $this->config->getOptions();
974+
975+
// The methods createView(), buildView() and finishView() are called
976+
// explicitly here in order to be able to override either of them
977+
// in a custom resolved form type.
978+
$view = $type->createView($this, $parent);
979+
980+
$type->buildView($view, $this, $options);
981+
982+
foreach ($this->children as $name => $child) {
983+
$view->children[$name] = $child->createView($view);
984+
}
985+
986+
$type->finishView($view, $this, $options);
987+
988+
return $view;
973989
}
974990

975991
/**

src/Symfony/Component/Form/FormFactory.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,13 @@ public function createNamedBuilder($name, $type = 'form', $data = null, array $o
8484
throw new UnexpectedTypeException($type, 'string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface');
8585
}
8686

87-
return $type->createBuilder($this, $name, $options);
87+
$builder = $type->createBuilder($this, $name, $options);
88+
89+
// Explicitly call buildForm() in order to be able to override either
90+
// createBuilder() or buildForm() in the resolved form type
91+
$type->buildForm($builder, $builder->getOptions());
92+
93+
return $builder;
8894
}
8995

9096
/**

src/Symfony/Component/Form/ResolvedFormType.php

Lines c A3E2 hanged: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ public function createBuilder(FormFactoryInterface $factory, $name, array $optio
114114
$builder = $this->newBuilder($name, $dataClass, $factory, $options);
115115
$builder->setType($this);
116116

117-
$this->buildForm($builder, $options);
118-
119117
return $builder;
120118
}
121119

@@ -124,28 +122,12 @@ public function createBuilder(FormFactoryInterface $factory, $name, array $optio
124122
*/
125123
public function createView(FormInterface $form, FormView $parent = null)
126124
{
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;
125+
return $this->newView($parent);
141126
}
142127

143128
/**
144129
* Configures a form builder for the type hierarchy.
145130
*
146-
* This method is protected in order to allow implementing classes
147-
* to change or call it in re-implementations of {@link createBuilder()}.
148-
*
149131
* @param FormBuilderInterface $builder The builder to configure.
150132
* @param array $options The options used for the configuration.
151133
*/
@@ -166,10 +148,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
166148
/**
167149
* Configures a form view for the type hierarchy.
168150
*
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.
151+
* This method is called before the children of the view are built.
173152
*
174153
* @param FormView $view The form view to configure.
175154
* @param FormInterface $form The form corresponding to the view.
@@ -192,10 +171,7 @@ public function buildView(FormView $view, FormInterface $form, array $options)
192171
/**
193172
* Finishes a form view for the type hierarchy.
194173
*
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.
174+
* This method is called after the children of the view have been built.
199175
*
200176
* @param FormView $view The form view to configure.
201177
* @param FormInterface $form The form corresponding to the view.
@@ -218,9 +194,6 @@ public function finishView(FormView $view, FormInterface $form, array $options)
218194
/**
219195
* Returns the configured options resolver used for this type.
220196
*
221-
* This method is protected in order to allow implementing classes
222-
* to change or call it in re-implementations of {@link createBuilder()}.
223-
*
224197
* @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
225198
*/
226199
public function getOptionsResolver()

src/Symfony/Component/Form/Tests/AbstractFormTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ abstract protected function createForm();
6060
*
6161
* @return FormBuilder
6262
*/
63-
protected function getBuilder($name = 'name', EventDispatcherInterface $dispatcher = null, $dataClass = null)
63+
protected function getBuilder($name = 'name', EventDispatcherInterface $dispatcher = null, $dataClass = null, array $options = array())
6464
{
65-
return new FormBuilder($name, $dataClass, $dispatcher ?: $this->dispatcher, $this->factory);
65+
return new FormBuilder($name, $dataClass, $dispatcher ?: $this->dispatcher, $this->factory, $options);
6666
}
6767

6868
/**

src/Symfony/Component/Form/Tests/CompoundFormTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
1616
use Symfony\Component\Form\FormError;
1717
use Symfony\Component\Form\Forms;
18+
use Symfony\Component\Form\FormView;
1819
use Symfony\Component\HttpFoundation\Request;
1920
use Symfony\Component\HttpFoundation\File\UploadedFile;
2021
use Symfony\Component\Form\Tests\Fixtures\FixedDataTransformer;
@@ -806,6 +807,65 @@ public function testGetErrorsAsStringDeep()
806807
$this->assertEquals("name:\n ERROR: Error!\nfoo:\n No errors\n", $parent->getErrorsAsString());
807808
}
808809

810+
// Basic cases are covered in SimpleFormTest
811+
public function testCreateViewWithChildren()
812+
{
813+
$type = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
814+
$options = array('a' => 'Foo', 'b' => 'Bar');
815+
$field1 = $this->getMockForm('foo');
816+
$field2 = $this->getMockForm('bar');
817+
$view = new FormView();
818+
$field1View = new FormView();
819+
$field2View = new FormView();
820+
821+
$this->form = $this->getBuilder('form', null, null, $options)
822+
->setCompound(true)
823+
->setDataMapper($this->getDataMapper())
824+
->setType($type)
825+
->getForm();
826+
$this->form->add($field1);
827+
$this->form->add($field2);
828+
829+
$test = $this;
830+
831+
$assertChildViewsEqual = function (array $childViews) use ($test) {
832+
return function (FormView $view) use ($test, $childViews) {
833+
/* @var \PHPUnit_Framework_TestCase $test */
834+
$test->assertSame($childViews, $view->children);
835+
};
836+
};
837+
838+
// First create the view
839+
$type->expects($this->once())
840+
->method('createView')
841+
->will($this->returnValue($view));
842+
843+
// Then build it for the form itself
844+
$type->expects($this->once())
845+
->method('buildView')
846+
->with($view, $this->form, $options)
847+
->will($this->returnCallback($assertChildViewsEqual(array())));
848+
849+
// Then add the first child form
850+
$field1->expects($this->once())
851+
->method('createView')
852+
->will($this->returnValue($field1View));
853+
854+
// Then the second child form
855+
$field2->expects($this->once())
856+
->method('createView')
857+
->will($this->returnValue($field2View));
858+
859+
// Again build the view for the form itself. This time the child views
860+
// exist.
861+
$type->expects($this->once())
862+
->method('finishView')
863+
->with($view, $this->form, $options)
864+
->will($this->returnCallback($assertChildViewsEqual(array('foo' => $field1View, 'bar' => $field2View))));
865+
866+
$this->assertSame($view, $this->form->createView());
867+
}
868+
809869
protected function createForm()
810870
{
811871
return $this->getBuilder()

0 commit comments

Comments
 (0)
0