Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data to buildForm() in Symfony 2.8, 3.0 and above

Tags:

php

symfony

My application currently passes data to my form type using the constructor, as recommended in this answer. However the Symfony 2.8 upgrade guide advises that passing a type instance to the createForm function is deprecated:

Passing type instances to Form::add(), FormBuilder::add() and the FormFactory::create*() methods is deprecated and will not be supported anymore in Symfony 3.0. Pass the fully-qualified class name of the type instead.

Before:    
$form = $this->createForm(new MyType());

After:
$form = $this->createForm(MyType::class);

Seeing as I can't pass data through with the fully-qualified class name, is there an alternative?

like image 709
Jonathan Avatar asked Dec 01 '15 18:12

Jonathan


2 Answers

This broke some of our forms as well. I fixed it by passing the custom data through the options resolver.

In your form type:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $this->traitChoices = $options['trait_choices'];

    $builder
        ...
        ->add('figure_type', ChoiceType::class, [
            'choices' => $this->traitChoices,
        ])
        ...
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'trait_choices' => null,
    ]);
}

Then when you create the form in your controller, pass it in as an option instead of in the constructor:

$form = $this->createForm(ProfileEditType::class, $profile, [
    'trait_choices' => $traitChoices,
]);
like image 146
sekl Avatar answered Nov 07 '22 22:11

sekl


Here's how to pass the data to an embedded form for anyone using Symfony 3. First do exactly what @sekl outlined above and then do the following:

In your primary FormType

Pass the var to the embedded form using 'entry_options'

->add('your_embedded_field', CollectionType::class, array(
          'entry_type' => YourEntityType::class,
          'entry_options' => array(
            'var' => $this->var
          )))

In your Embedded FormType

Add the option to the optionsResolver

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Yourbundle\Entity\YourEntity',
        'var' => null
    ));
}

Access the variable in your buildForm function. Remember to set this variable before the builder function. In my case I needed to filter options based on a specific ID.

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $this->var = $options['var'];

    $builder
        ->add('your_field', EntityType::class, array(
          'class' => 'YourBundle:YourClass',
          'query_builder' => function ($er) {
              return $er->createQueryBuilder('u')
                ->join('u.entity', 'up')
                ->where('up.id = :var')
                ->setParameter("var", $this->var);
           }))
     ;
}
like image 6
mcriecken Avatar answered Nov 07 '22 20:11

mcriecken