Symfony2 - How to set and get options when using a form class?

I use form classes to create various forms in my project.

In the Entity file for the buildForm function, there is a secondary parameter "array $ options" (this is shown in the official Symfony 2 documentation, but never mentioned!)

I fed the array to the createForm function in my controller, but now I'm completely fixated on how to get the stored values?

$form = $this->createForm(new ProductType(array(), array('id' => '2')), $product); 

The only thing I found about getting parameters was using the getOption () function, but this does not exist in Symfony 2 (the message I found was from 2010).

I tried using:

 $id = $options['id']; 

But when I try to use $ id anywhere, I get an error:

Note: Undefined index: id

What gives?

How to get my values ​​from $ options array? Do I really install them correctly?

EDIT - Additional Code:

Form class

 <?php namespace DEMO\DemoBundle\Form\Product; use Doctrine\ORM\EntityRepository; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; class ProductType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder ->add('name') ->add('slug') ->add('reference') ->add('description') ->add('active_from') ->add('active_till') ->add('is_active') ->add('category', 'entity', array( 'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 'query_builder' => function(EntityRepository $er) { return $er->createQueryBuilder('u') ->where('u.section = :id') ->setParameter('id', ***ID VARIABLE NEEDS TO GO HERE***) ->orderBy('u.root', 'ASC') ->addOrderBy('u.lft', 'ASC'); }, 'empty_value' => 'Choose an option', 'property' => 'indentedName', )); } public function getDefaultOptions() { return array( 'data_class' => 'DEMO\DemoBundle\Entity\Product\Product' ); } public function getName() { return 'demo_demobundle_product_type'; } } 
+6
source share
6 answers

Well, it turns out the Gregoires answer was very close, but it gave me the error "Undefined variable" when actually trying, but the variable in the createQueryBuilder function.

I spent some time trying to figure out why I found the problem. You must add an additional parameter to the function in the query_builder option, for example:

 'query_builder' => function(EntityRepository $er) use ($options) { return $er->createQueryBuilder('u') ->where('u.section = :id') ->setParameter('id', $options['id']) ->orderBy('u.root', 'ASC') ->addOrderBy('u.lft', 'ASC'); }, 

The magic setting used is ($ options). "This allows you to successfully use $ options ['id'] in Query Builder.

+1
source

I think you are not installing them properly in the first place. You must give them the third argument to createForm()

EDIT: this is what the form class looks like:

 <?php namespace DEMO\DemoBundle\Form\Product; use Doctrine\ORM\EntityRepository; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; class ProductType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder ->add('name') ->add('slug') ->add('reference') ->add('description') ->add('active_from') ->add('active_till') ->add('is_active') ->add('category', 'entity', array( 'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 'query_builder' => function(EntityRepository $er) use($options) { return $er->createQueryBuilder('u') ->where('u.section = :id') ->setParameter('id', $options['id']) ->orderBy('u.root', 'ASC') ->addOrderBy('u.lft', 'ASC'); }, 'empty_value' => 'Choose an option', 'property' => 'indentedName', )); } public function getDefaultOptions() { return array( 'data_class' => 'DEMO\DemoBundle\Entity\Product\Product', 'id' => null ); } public function getName() { return 'demo_demobundle_product_type'; } } 
+16
source

Let me show you what worked for me

In the controller:

 $form = $this->createForm(new UsersType(), $entity, array( 'attr' => array('locationId' => $currentLocationId))); 

In FormType:

 ->add('location', 'entity', array( 'class' => 'Ro\RoinventBundle\Entity\Locations', 'query_builder' => function (\Doctrine\ORM\EntityRepository $er) use ($options) { if (isset($options['attr']['locationId']) && ($options['attr']['locationId'] != NULL)) { return $er->createQueryBuilder('Locations') ->where('Locations.id = :param') ->setParameter('param', $options['attr']['locationId']); } //else do what you want }, )); 
+7
source

Apparently this is not with getDefaultOptions() anymore, but with setDefaultOptions() .

Otherwise said

The parameter "my_custom_option" does not exist. The following options are known: "action", "attr", "auto_initialize", ...

So, for me, I had to update setDefaultOptions as follows:

 public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array('my_custom_option' => false)); // Others if needed, like in the documentation for : 'data_class' => 'VENDOR\Bundle\Entity\MyEntity', 'csrf_protection' => true } 

And then you can get it in the buildForm method

 public function buildForm(FormBuilderInterface $builder, array $options) { $myCustomOption = $options['my_custom_option']; } 
+7
source

Good in line with this Google Groups

"greg0ire" was right, in fact I tried it and it works great !!!. You said, “I really don't want to hack into any of the core structures, but you don’t end up using a better approach. In fact, from my point of view, you end up doing what you did not want to do.

So in the end you should do this:

in the form of type

 public function buildForm(FormBuilder $builder, array $options) { $builder ->add('name') ->add('slug') ->add('reference') ->add('description') ->add('active_from') ->add('active_till') ->add('is_active') ->add('category', 'entity', array( 'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 'query_builder' => function(EntityRepository $er) { return $er->createQueryBuilder('u') ->where('u.section = :id') ->setParameter('id', $options['id']) ->orderBy('u.root', 'ASC') ->addOrderBy('u.lft', 'ASC'); }, 'empty_value' => 'Choose an option', 'property' => 'indentedName', )); } public function getDefaultOptions() { return array( 'data_class' => 'DEMO\DemoBundle\Entity\Product\Product' 'id' => null ); } 

And in the controller

 $form = $this->createForm(new ProductType(), $product, array('id' => $id )); 
+5
source

Pass parameters through the __construct class __construct , for example:

 use Doctrine\ORM\EntityRepository; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; class ProductType extends AbstractType { private $options = array(); public function buildForm(FormBuilder $builder, array $options) { $builder ->add('name') ->add('slug') ->add('reference') ->add('description') ->add('active_from') ->add('active_till') ->add('is_active') ->add('category', 'entity', array( 'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory', 'query_builder' => function(EntityRepository $er) { return $er->createQueryBuilder('u') ->where('u.section = :id') ->setParameter('id', $this->options['id']) ->orderBy('u.root', 'ASC') ->addOrderBy('u.lft', 'ASC'); }, 'empty_value' => 'Choose an option', 'property' => 'indentedName', )); } public function getDefaultOptions() { return array( 'data_class' => 'DEMO\DemoBundle\Entity\Product\Product' ); } public function getName() { return 'demo_demobundle_product_type'; } public function __construct(array $options) { $this->options = $options; } } 

And then you can do:

 new ProductType(array('id'=>1)); 
+1
source

Source: https://habr.com/ru/post/914507/


All Articles