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

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

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

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

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

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

Я пытался с помощью:

<code>$id = $options['id'];
</code>

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

Notice: Undefined index: id

Что дает?

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

РЕДАКТИРОВАТЬ - больше код:

Форма класса

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

Ответы на вопрос(6)

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

$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" не существует. Известные опции: «action», «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'];
}

Пропустите опции через класс форм__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));
 Mr Pablo04 мая 2012 г., 10:02
Ха-ха, да, уже несколько дней назад понял, зацени мой ответ :) Спасибо за помощь!
 Mr Pablo01 мая 2012 г., 10:18
Я попробовал этот метод, и у меня возникла ошибка «Неопределенная переменная». Я скопировал его точно, поэтому я не могу понять, почему я получаю эту ошибку, насколько я понимаю, переменная IS устанавливается ...
 greg0ire03 мая 2012 г., 18:09
добавление "use ($ this)", вероятно, должно сработать
Решение Вопроса

оказывается, ответ Грегуара был очень близок, но он выдал мне ошибку «Неопределенная переменная», когда пытался фактически перевести переменную в функцию 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');
                },

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

 Flukey03 мая 2012 г., 17:53
ok :) спасибо за разъяснение
 Flukey03 мая 2012 г., 17:50
это был мой ответ, а не greg0ires ...
 Mr Pablo03 мая 2012 г., 17:52
Извините, это на самом деле реализовано с помощью ответа greg0ires, я неправильно скопировал код. Отредактировал это, чтобы убрать это

вы не правильно их настраиваете. Вы должны дать им в качестве третьего аргумента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';
    }
}
 Mr Pablo30 апр. 2012 г., 17:03
Tbh, я действительно не хочу "взламывать" какую-либо структуру ядра. Функция buildForm () явно имеет вторичный параметр для установки массива опций. Я хочу знать, как это правильно используется.
 greg0ire30 апр. 2012 г., 17:08
Это не хакерская структура ядра, это путь, метод getDefaultOptions () - это метод, который находится в ВАШЕМ классе формы (это если вы сгенерировали форму с помощью задачи cli). Это там, чтобы вы могли изменить его. Если вы мне не верите, верьте документации: Symfony.com / док / мастер / книга / forms.html, который показывает примеры модификаций этого метода.
 Mr Pablo30 апр. 2012 г., 16:36
Я полагаю, что 3-й вариант для createForm () - установить такие параметры, как: "attr", "by_reference", "cascade_validation", "csrf_field_name", "csrf_protection", "csrf_provider", "data", "data_class" , "отключен", "пустые_данные", "error_bubbling", "error_delay", "error_mapping", "error_type", "field_error_type", "help_block", "help_inline" и т. д. и т. д. (в основном, я пытался, и он говорит: «Опция "id" не существует. ")
 greg0ire30 апр. 2012 г., 16:47
Вы можете адаптировать метод getDefaultOptions () вашего класса формы, чтобы сообщить своей форме об этой опции и избежать этого сообщения.
 Mr Pablo30 апр. 2012 г., 17:13
На этой странице не показано, как настроить getDefaultOptions (). Он только показывает, как использовать некоторые из доступных опций для этого метода, такие как CSRF Protection и установка data_class. Пожалуйста, нарисуйте, где именно показано, как настроить метод, который позволил бы мне добавлять свои собственные параметры?

Google Groups

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

Так что в конце ты должен сделать это:

в форме типа

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

Ваш ответ на вопрос