Search code examples
symfonysymfony-formssymfony4

Getting entity in embedded collection of forms


In my edit form I need to get the entity object in embedded form. This is my main edit form:

class OrderCollectionsEditType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('sampleCollections', CollectionType::class, [
                'entry_type' => SampleCollectionType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false
            ])
        ;
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Order::class,
        ]);
    }
}

and the embedded one:

class SampleCollectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $sampleCollection = $builder->getData();
        $builder
            ->add('methods', EntityType::class, [
                'class' => Method::class,
                'multiple' => true,
            ])
            {...}
        ;
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => SampleCollection::class,
        ]);
    }
}

The form created in controller:

$form = $this->createForm(OrderCollectionsEditType::class, $order);

And the problem is that the $sampleCollection returns NULL, but the form is properly filled by the values. Is there any other way to get the entity object?


Solution

  • Unfortunately, what's suggested in this answer ($options['data']) doesn't work with CollectionType, there's no 'data' index.

    We can use PRE_SET_DATA form event and then get the entity object in listener function:

    class SampleCollectionType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
                    $sampleCollection = $event->getData();
    
                    $form = $event->getForm();
                    $form->add('methods', EntityType::class, [
                        'class' => Method::class,
                        'multiple' => true,
                    ]);
                })
            ;
        }
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
                'data_class' => SampleCollection::class,
            ]);
        }
    }