diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 636d84404a..e22e5826fb 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 5.1.0 ----- + * Added `collection_entry` block prefix to `CollectionType` entries * Added a `choice_filter` option to `ChoiceType` * Added argument `callable|null $filter` to `ChoiceListFactoryInterface::createListFromChoices()` and `createListFromLoader()` - not defining them is deprecated. * Added a `ChoiceList` facade to leverage explicit choice list caching based on options diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php b/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php index b441f08ce6..d4023ecb5f 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php @@ -72,8 +72,32 @@ class CollectionType extends AbstractType */ public function finishView(FormView $view, FormInterface $form, array $options) { - if ($form->getConfig()->hasAttribute('prototype') && $view->vars['prototype']->vars['multipart']) { - $view->vars['multipart'] = true; + $prefixOffset = -1; + // check if the entry type also defines a block prefix + /** @var FormInterface $entry */ + foreach ($form as $entry) { + if ($entry->getConfig()->getOption('block_prefix')) { + --$prefixOffset; + } + + break; + } + + foreach ($view as $entryView) { + array_splice($entryView->vars['block_prefixes'], $prefixOffset, 0, 'collection_entry'); + } + + /** @var FormInterface $prototype */ + if ($prototype = $form->getConfig()->getAttribute('prototype')) { + if ($view->vars['prototype']->vars['multipart']) { + $view->vars['multipart'] = true; + } + + if ($prefixOffset > -2 && $prototype->getConfig()->getOption('block_prefix')) { + --$prefixOffset; + } + + array_splice($view->vars['prototype']->vars['block_prefixes'], $prefixOffset, 0, 'collection_entry'); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php index 583a7c4f8b..a610c24a04 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; use Symfony\Component\Form\Tests\Fixtures\Author; use Symfony\Component\Form\Tests\Fixtures\AuthorType; +use Symfony\Component\Form\Tests\Fixtures\BlockPrefixedFooTextType; class CollectionTypeTest extends BaseTypeTest { @@ -404,6 +405,62 @@ class CollectionTypeTest extends BaseTypeTest $this->assertFalse($child->createView()->vars['prototype']->vars['required'], '"Prototype" should not be required'); } + public function testEntriesBlockPrefixes() + { + $collectionView = $this->factory->createNamed('fields', static::TESTED_TYPE, [''], [ + 'allow_add' => true, + ]) + ->createView() + ; + + $expectedBlockPrefixes = [ + 'form', + 'text', + 'collection_entry', + '_fields_entry', + ]; + + $this->assertCount(1, $collectionView); + $this->assertSame($expectedBlockPrefixes, $collectionView[0]->vars['block_prefixes']); + $this->assertSame($expectedBlockPrefixes, $collectionView->vars['prototype']->vars['block_prefixes']); + } + + public function testEntriesBlockPrefixesWithCustomBlockPrefix() + { + $collectionView = $this->factory->createNamed('fields', static::TESTED_TYPE, [''], [ + 'entry_options' => ['block_prefix' => 'field'], + ]) + ->createView() + ; + + $this->assertCount(1, $collectionView); + $this->assertSame([ + 'form', + 'text', + 'collection_entry', + 'field', + '_fields_entry', + ], $collectionView[0]->vars['block_prefixes']); + } + + public function testEntriesBlockPrefixesWithCustomBlockPrefixedType() + { + $collectionView = $this->factory->createNamed('fields', static::TESTED_TYPE, [''], [ + 'entry_type' => BlockPrefixedFooTextType::class, + ]) + ->createView() + ; + + $this->assertCount(1, $collectionView); + $this->assertSame([ + 'form', + 'block_prefixed_foo_text', + 'collection_entry', + 'foo', + '_fields_entry', + ], $collectionView[0]->vars['block_prefixes']); + } + public function testSubmitNull($expected = null, $norm = null, $view = null) { parent::testSubmitNull([], [], []); diff --git a/src/Symfony/Component/Form/Tests/Fixtures/BlockPrefixedFooTextType.php b/src/Symfony/Component/Form/Tests/Fixtures/BlockPrefixedFooTextType.php new file mode 100644 index 0000000000..3fda7a55dd --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Fixtures/BlockPrefixedFooTextType.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Fixtures; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class BlockPrefixedFooTextType extends AbstractType +{ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('block_prefix', 'foo'); + } +}