Symfony2 - How to set, and get, options when using a Form Class?

后端 未结 6 1466
暖寄归人
暖寄归人 2021-02-06 08:29

I am using Form Classes to build the various form in my project.

In the Entity Type file, for the buildForm function, there is a secondary parameter of \"array $options\

相关标签:
6条回答
  • 2021-02-06 08:53

    Pass the options through the forms class __construct method, like so:

    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));
    
    0 讨论(0)
  • 2021-02-06 08:54

    Well acording to this Google Groups

    "greg0ire" was right, in fact I have tried it and works perfect!!!. You said "I dont really want to go about "hacking" any of the core structure" but you end up using no the best approach.. in matter of fact, from my point of view, you end up doing what you didn't want to do.

    So at the end you should do this:

    at the formType

    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 ));
    
    0 讨论(0)
  • 2021-02-06 09:00

    Apparently it's not with getDefaultOptions() anymore, but with setDefaultOptions().

    Otherwise it says

    The option "my_custom_option" does not exist. Known options are: "action", "attr", "auto_initialize", ...

    So, for me I had to update setDefaultOptions like this :

    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 retrieve it in the buildForm method

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $myCustomOption = $options['my_custom_option'];
    }
    
    0 讨论(0)
  • 2021-02-06 09:02

    Let me show you what worked for me

    In the Controller:

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

    In the 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
    },
    ));
    
    0 讨论(0)
  • 2021-02-06 09:06

    I think you're not setting them properly in the first place. You're supposed to give them as third argument to createForm()

    EDIT: Here is how your form class could look:

    <?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';
        }
    }
    
    0 讨论(0)
  • 2021-02-06 09:06

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

    I spent a while trying to figure out why and found the issue. You have to add an extra parameter to the function in the "query_builder" option, like such:

    '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 being "use ($options)". This allows you to successfully use $options['id'] in the Query Builder.

    0 讨论(0)
提交回复
热议问题