Bladeren bron

Detect type when adding a FormBuilderInterface (#4101)

Fabien Bourigault 8 jaren geleden
bovenliggende
commit
71a63ac370
3 gewijzigde bestanden met toevoegingen van 91 en 0 verwijderingen
  1. 5 0
      Form/FormMapper.php
  2. 52 0
      Resources/doc/reference/form_types.rst
  3. 34 0
      Tests/Form/FormMapperTest.php

+ 5 - 0
Form/FormMapper.php

@@ -89,6 +89,11 @@ class FormMapper extends BaseGroupedMapper
 
         $group = $this->addFieldToCurrentGroup($label);
 
+        // Try to autodetect type
+        if ($name instanceof FormBuilderInterface && null === $type) {
+            $fieldDescriptionOptions['type'] = get_class($name->getType()->getInnerType());
+        }
+
         if (!isset($fieldDescriptionOptions['type']) && is_string($type)) {
             $fieldDescriptionOptions['type'] = $type;
         }

+ 52 - 0
Resources/doc/reference/form_types.rst

@@ -561,6 +561,58 @@ example above:
 Other specific field configuration options are detailed in the related
 abstraction layer documentation.
 
+Adding a FormBuilderInterface
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+You can add Symfony ``FormBuilderInterface`` instances to the ``FormMapper``. This allows you to
+re-use a model form type. When adding a field using a ``FormBuilderInterface``, the type is guessed.
+
+Given you have a ``PostType`` like this:
+
+.. code-block:: php
+
+    <?php
+    // src/AppBundle/Form/PostType.php
+
+    class PostType extends AbstractType
+    {
+        public function buildForm(FormBuilderInterface $builder, array $options)
+        {
+            $builder
+                ->add('author', EntityType::class, [
+                    'class' => User::class
+                ])
+                ->add('title', TextType::class)
+                ->add('body', TextareaType::class)
+            ;
+        }
+    }
+
+you can reuse it like this:
+
+.. code-block:: php
+
+    <?php
+    // src/AppBundle/Admin/Post.php
+
+    class Post extend AbstractAdmin
+    {
+        protected function configureFormFields(FormMapper $formMapper)
+        {
+            $builder = $formMapper->getFormBuilder()->getFormFactory()->createBuilder(PostType::class);
+
+            $formMapper
+                ->with('Post')
+                    ->add($builder->get('title'))
+                    ->add($builder->get('body'))
+                ->end()
+                ->with('Author')
+                    ->add($builder->get('author'))
+                ->end()
+            ;
+        }
+    }
+
+
 Types options
 -------------
 

+ 34 - 0
Tests/Form/FormMapperTest.php

@@ -338,10 +338,44 @@ class FormMapperTest extends \PHPUnit_Framework_TestCase
             ->method('getName')
             ->will($this->returnValue('foo'));
 
+        $formType = $this
+            ->getMockBuilder('Symfony\Component\Form\ResolvedFormTypeInterface')
+            ->getMock();
+
+        $innerType = $this
+            ->getMockBuilder('Symfony\Component\Form\Extension\Core\Type\FormType')
+            ->getMock();
+
+        $formType->expects($this->once())
+            ->method('getInnerType')
+            ->will($this->returnValue($innerType));
+
+        $formBuilder->expects($this->once())
+            ->method('getType')
+            ->will($this->returnValue($formType));
+
         $this->formMapper->add($formBuilder);
         $this->assertSame($this->formMapper->get('foo'), $formBuilder);
     }
 
+    public function testAddFormBuilderWithType()
+    {
+        $formBuilder = $this
+            ->getMockBuilder('Symfony\Component\Form\FormBuilder')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $formBuilder->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue('foo'));
+
+        $formBuilder->expects($this->never())
+            ->method('getType');
+
+        $this->formMapper->add($formBuilder, 'Symfony\Component\Form\Extension\Core\Type\FormType');
+        $this->assertSame($this->formMapper->get('foo'), $formBuilder);
+    }
+
     public function testGroupRemovingWithoutTab()
     {
         $this->formMapper->with('foobar');