来自ORM的Symfony2选择表格数据

时间:2016-12-12 12:02:39

标签: symfony

有这样的表格:

class ScanType extends AbstractType
{
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
                $builder->add('scantarget', 'entity', array(
                                        'class' => 'AppBundle:Website',
                                        'property' => 'url'
                                        ));
        }


        public function getDefaultOptions(array $options) {
        return array(
            'data_class' => 'AppBundle\Entity\Website',
        );
    }


}

需要仅使用特定用户标识的网址

填充它

在控制器中:

         /**
         * @Route("/verification-ok", name="verifyurlok")
         */
        public function verifyurlActionOK(Request $request)
        {
                $user = $this->getUser();



                if($user)
                {
                        $userid=$user->getId();

                        $websites = $this->getDoctrine()->getRepository('AppBundle:Website')->findByUser($userid);


                        $form = $this->createForm(ScanType::class, $websites);

但是,$网站未正确传递给FormBuilder,在我的选择框中,我看到所有条目:(网站实体的所有可能值。

如何在表单中显示仅传递$网站(选择框)?那么只有特定用户标识的网站?

谢谢,

更新1

表格

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

class ScanType extends AbstractType
{

private $tokenStorage;

    public function __construct(TokenStorageInterface $tokenStorage)
    {
                $this->tokenStorage = $tokenStorage;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
                $user = $this->tokenStorage->getToken()->getUser();
                if (!$user) {
                   throw new \LogicException(
                   'The FriendMessageFormType cannot be used without an authenticated user!'
                   );
                }


                $builder->addEventListener(
                FormEvents::PRE_SET_DATA,
                function (FormEvent $event) use ($user) {
                $form = $event->getForm();

                $formOptions = array(
                    'class' => 'AppBundle\Entity\Website',
                    'property' => 'user',
                    'query_builder' => function (EntityRepository $er) use ($user) {
                        // build a custom query
                        return $er->createQueryBuilder('u')->addOrderBy('user', 'DESC');

                        // or call a method on your repository that returns the query builder
                        // the $er is an instance of your UserRepository
                        // return $er->createOrderByFullNameQueryBuilder();
                    },
                );

                // create the field, this is similar the $builder->add()
                // field name, field type, data, options
                $form->add('url', ScanType::class, $formOptions);
            }
        );
    }


        public function getDefaultOptions(array $options) {
        return array(
            'data_class' => 'AppBundle\Entity\Website',
        );
    }


}

控制器:

 $form = $this->createForm(ScanType::class);

config.yml

services:
    app.form.scan:
        class: AppBundle\Form\ScanType
        arguments: ['@security.token_storage']
        tags:
            - { name: form.type }

不幸的是,收到此错误:

request.CRITICAL: Uncaught PHP Exception Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException: "The options "class", "property", "query_builder" do not exist. Defined options are: "action", "allow_extra_fields", "attr", "auto_initialize", "block_name", "by_reference",

解决方案:

谢谢@Medard

形式:

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ScanType extends AbstractType
{      
            private $websites;


            public function buildForm(FormBuilderInterface $builder, array $options)
            {
                    $this->websites = $options['trait_choices'];

                    $builder->add('scantarget', 'entity', array(
                          'class' => 'AppBundle:Website',
                          'property' => 'url',
                          'choices' => $this->websites
                        ));
            }


           public function setDefaultOptions(OptionsResolverInterface $resolver)
           {
                    $resolver->setDefaults(array(
                         'data_class' => null,
                         'trait_choices' => null,

                        ));
           }


}

控制器:

 $form = $this->createForm(ScanType::class, $websites, array(
        'trait_choices' => $websites
    ));

作品!!!

2 个答案:

答案 0 :(得分:0)

好吧,你没有设定选择。试试这个:

   class ScanType extends AbstractType
    {      
            private $websites;


            public function buildForm(FormBuilderInterface $builder, array $options)
            {
              $this->websites = $options['trait_choices'];

                    $builder->add('scantarget', 'entity', array(
                          'class' => 'AppBundle:Website',
                          'property' => 'url',
                          'choices' => $this->websites
                        ));
            }


            public function setDefaultOptions(array $options) {
            return array(
                'data_class' => 'AppBundle\Entity\Website',
                'trait_choices' => null,
            );
        }


    }

在控制器中通过网站:

$form = $this->createForm(ScanType::class, $websites, array(
        'trait_choices' => $websites,
    ));

答案 1 :(得分:0)

您的表单会显示所有网站条目,因为您在构建表单时不会在add()方法中限制它们。

您应该阅读食谱的这一部分:http://symfony.com/doc/current/form/dynamic_form_modification.html#form-events-user-data