3

CategoryType フォームから「作成者」フィールドの値を設定しようとしています。FOSバンドルでログインしている現在のユーザーのユーザーIDにしたい。

私のCategoryTypeフォーム:

namespace My\CategoryBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CategoryType extends AbstractType
{
    private $userId;

    public function __construct(array $userId)
    {
        $this->userId = $userId;
    }

     /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('author')
            ->add('content')
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'My\CategoryBundle\Entity\Category',
            'auteur' => $this->userId
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'my_categorybundle_category';
    }
}

そして私のコントローラのアクション:

public function addAction()
{
    $category = new Category;
    $user = $this->get('security.context')->getToken()->getUser(); 
    $userId = $user->getId();

    $form = $this->get('form.factory')->create(new CategoryType(), array( 'author' => $userId));

    $request = $this->get('request');
    if ($request->getMethod() == 'POST') {
        $form->bind($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($category);
            $em->flush();

        return $this->redirect($this->generateUrl('mycategory_voir',
            array('id' => $category->getId())));
        }
    }
    return $this->render('MyCategoryBundle:Category:add.html.twig',
        array(
            'form' => $form->createView(),
        ));
}

アクションの実行中にこのエラーをキャッチします。

キャッチ可能な致命的なエラー: My\CategoryBundle\Form\CategoryType::__construct() に渡される引数 1 は、指定されていない配列である必要があり、/My/CategoryBundle/Controller/CategoryController.php の 55 行目で呼び出され、/My/CategoryBundle で定義されている必要があります/Form/CategoryType.php 13行目

フォームに渡しているのはすでに配列ではありませんか?

4

2 に答える 2

10

あなたの問題はこの行にあります

$form = $this->get('form.factory')->create(new CategoryType(), array( 'author' => $userId));

の契約を満足していませんMy\CategoryBundle\FormCategoryType::__construct()。ここで、別の見方をしてみましょう。

$form = $this->get('form.factory')->create(
    new CategoryType(/* You told PHP to expect an array here */)
  , array('author' => $userId)
);

2番目の引数として送信する配列Symfony\Component\Form\FormFactory::create()は、最終的に$options配列として注入されるものですMy\CategoryBundle\Form\CategoryType::buildForm()

私が見ているように、これを解決するにはいくつかの方法があります

  1. 引数の署名を更新し、My\CategoryBundle\FormCategoryType::__construct()ユーザー オブジェクト全体を渡す/受け取るように呼び出します (ID だけでなく、この時点で Doctrine の関係を操作していることを思い出してください。マップ先の下位レベルの外部キーではありません)。

    namespace My\CategoryBundle\Form;
    
    use My\CategoryBundle\Entity\User; /* Or whatver your User class is */
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class CategoryType extends AbstractType
    {
        private $author;
    
        public function __construct( User $author )
        {
            $this->author = $author;
        }
    

    $form = $this->get('form.factory')->create(
        new CategoryType(
          $this->get('security.context')->getToken()->getUser()
        )
    );
    
  2. を型のコンストラクターに注入しないでくださいUser。オプションに処理させてください。

    namespace My\CategoryBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class CategoryType extends AbstractType
    {
        private $userId;
    
         /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('title')
                ->add('author', 'hidden', array('data'=>$options['author']))
                ->add('content')
            ;
        }
    
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'My\CategoryBundle\Entity\Category'
            ));
        }
    
        /**
         * @return string
         */
        public function getName()
        {
            return 'my_categorybundle_category';
        }
    }
    
  3. 作成者をフォームに入れてコントローラーに処理させることさえ気にしません

    $form = $this->get('form.factory')->create(
        new CategoryType()
      , array('author' => $this->get('security.context')->getToken()->getUser() )
    );
    

    if ($request->getMethod() == 'POST') {
        $form->bind($request);
    
        if ($form->isValid()) {
            $category->setAuthor(
              $this->get('security.context')->getToken()->getUser()
            );
            $em = $this->getDoctrine()->getManager();
            $em->persist($category);
            $em->flush();
    
        return $this->redirect($this->generateUrl('mycategory_voir',
            array('id' => $category->getId())));
        }
    }
    
  4. フォーム タイプをサービスに変換し、DI コンテナーを使用してセキュリティ コンテキストを挿入します。

    アプリ/設定/config.yml

    services:
      form.type.my_categorybundle_category:
        class: My\CategoryBundle\Form\CategoryType
        tags:
          - {name: form.type, alias: my_categorybundle_category}
        arguments: ["%security.context%"]
    

    タイプを更新してセキュリティ コンテキストを受け取る

    namespace My\CategoryBundle\Form;
    
    use Symfony\Component\Security\Core\SecurityContext;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class CategoryType extends AbstractType
    {
        private $author;
    
        public function __construct( SecurityContext $security )
        {
            $this->author = $security->getToken()->getUser();
        }
    

    次に、コントローラーで、サービス名を使用してフォームを作成します

    $form = $this->get('form.factory')->create('my_categorybundle_category');
    
于 2013-11-06T15:19:27.987 に答える
0

現在のコードは、コンストラクトcreate()ではなく、配列をメソッドに渡します。CategoryType

$form = $this->get('form.factory')->create(new CategoryType(), array( 'author' => $userId));

する必要があります

$form = $this->get('form.factory')->create(new CategoryType(array( 'author' => $userId)));
于 2013-11-06T15:16:07.490 に答える