Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass parameter to FormType constructor from controller

In Symfony2.7 i was able to pass parameter to Form Type constructor directly from controller while creating the form, however in Symfony3 i'm not able to do it!

Before in Symfony2.7

$postedBy = $this->getUser()->getFullname();
$form = $this->createForm(new NewsType($postedBy));

After in Symfony3

$form = $this->createForm(NewsType::class); // no idea how to pass parameter?

Update: I also wanted to access it from:

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    // how to access posted_by_name here which is sent from controller
}

Any help will be highly appreciated..

like image 813
Muzafar Ali Avatar asked Apr 28 '16 04:04

Muzafar Ali


3 Answers

Thanks for your time! i resolved this myself:

I removed parameter from NewsType constructor and added data to postedBy form field using $options array, and passed data to $options array from controller, please check following:

NewsType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('postedBy', HiddenType::class, array(
            'data' => $options['postedBy']
          )
        )
    ;
}

// WARNING: this is a MANDATORY block! Only options described here will be allowed to be passed.
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'postedBy' => null,
    ));
}

Controller

$form = $this->createForm(NewsType::class, $news, array(
    'postedBy' => $this->getUser()->getFullname(),
);

UPDATE: Please use below code if you want to access $options array from addEventListener:

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $postedBy = $event->getForm()->getConfig()->getOptions()['postedBy'];
}

Hope it helps somebody! 

like image 156
Muzafar Ali Avatar answered Nov 20 '22 12:11

Muzafar Ali


You need to define your form as service.

namespace AppBundle\Form\Type;

use App\Utility\MyCustomService;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class NewsType extends AbstractType
{
    private $myCustomService;

    private $myStringParameter;

    public function __construct(MyCustomService $service, $stringParameter)
    {
        $this->myCustomService   = $service;
        $this->myStringParameter = $stringParameter;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Your code
    }
}

Add to your service configuration:

#src/AppBundle/Resources/config/services.yml
services:
    app.form.type.task:
        class: AppBundle\Form\Type\NewsType
        arguments:
            - "@app.my_service"
            - "posted_by_name"
        tags:
            - { name: form.type }
like image 45
jkucharovic Avatar answered Nov 20 '22 10:11

jkucharovic


You are both right.

@Muzafar and @jkucharovic, the question is when to use which...

As Bernard Schussek shows in Symfony Forms 101:

1 Don't pass Dynamic Data to constructor..

enter image description here

2 ... but use Custom Options instead

enter image description here

3 Do pass Global Settings to constructor (or services)

enter image description here

enter image description here

like image 11
Mick Avatar answered Nov 20 '22 11:11

Mick