Symfony2 – Как установить и получить опции при использовании класса формы?

Я использую классы форм для создания различной формы в моем проекте.

В файле типа Entity для функции buildForm имеется вторичный параметр «array $ options» (это показано в официальной документации Symfony 2, но никогда не упоминалось!)

Я подал массив в функцию createForm в моем контроллере, но теперь я полностью зациклен на том, как получить сохраненные значения?

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

Единственное, что я нашел о получении опций, это использование функции getOption (), но это не существует в Symfony 2 (сообщение, которое я нашел, было с 2010 года).

Я пробовал использовать:

 $id = $options['id']; 

Но когда я пытаюсь использовать $ id в любом месте, я получаю ошибку:

Примечание. Неопределенный индекс: id

Что дает?

Как получить мои значения из массива $ options? Я даже правильно их устанавливаю?

EDIT – Дополнительный код:

Класс формы

 <?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'; } } 

Я думаю, вы не ставите их должным образом в первую очередь. Вы должны дать им третий аргумент createForm()

EDIT: вот как выглядит класс формы:

 <?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'; } } 

Позвольте мне показать вам, что сработало для меня

В контроллере:

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

В 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 }, )); 

По-видимому, это не с getDefaultOptions() , а с setDefaultOptions() .

В противном случае

Опция «my_custom_option» не существует. Известные варианты: «действие», «attr», «auto_initialize», …

Итак, для меня мне пришлось обновить setDefaultOptions следующим образом:

 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 } 

И затем вы можете получить его в методе buildForm

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

Хорошо в соответствии с этими группами Google

«greg0ire» был прав, на самом деле я пробовал его и отлично работает !!!. Вы сказали: «Я действительно не хочу заниматься« взломом »любой из основных структур», но в конечном итоге вы не используете лучший подход. По сути, с моей точки зрения, вы в конечном итоге делаете то, что не делали хотеть сделать.

Поэтому в конце вы должны сделать это:

в форме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 ); } 

И в контроллере

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

Передайте параметры через метод класса __construct , например:

 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; } } 

И тогда вы можете сделать:

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

Ну, оказывается, ответ Gregoires был очень близок, но дал мне и ошибку «Неопределенная переменная» при попытке на самом деле, но переменная в функцию createQueryBuilder.

Я потратил некоторое время, пытаясь понять, почему и нашел проблему. Вы должны добавить дополнительный параметр к функции в опции «query_builder», например:

 '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'); }, 

Магическая настройка «use ($ options)». Это позволяет успешно использовать $ options ['id'] в Query Builder.