2

データを「ユーザーオブジェクト」に転送してDBに永続化するために、データを「キャッチ」する必要があるフォームを作成しました。

そのためには、次の手順に従います。

  1. ユーザーオブジェクトを作成する
  2. UserRepositoryを作成して永続化し、フェッチします(Entity Managerを介して)
  3. フォームを「マップ」するクラスを作成します
  4. 全体をレンダリングするためのルートとテンプレートを作成します

それで、それらの最初の2つをステップオーバーして、3番目のステップを一緒に見てみましょう

<?php
namespace Sestante\UserBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\Collection;

class AddUserType extends AbstractType
{
    public function BuildForm(FormBuilder $builder, array $options)
    {
        $builder->add('username','text')
                ->add('email','email')
                ->add('id','hidden')
                ->add('password','text')
                ;
    }

    public function getName()
    {
        return 'AddUser';
    }

これは、「フォームハンドル」用に作成したクラスの一部です。
明らかに私は自分のフォームにある種の検証を追加したいと思っています、そしてsymfony2の本に続いて私はこれをしました

public function getDefaultOptions(array $options)
{
    $collectionConstraint = new Collection(array(
        'username'=> new MinLength(4),
        'email'=>new Email(array('message'=>'invalid email address')),
    ));

    return array(
        'data_class' => 'Sestante\UserBundle\Entity\User',
        'validation_constraint' => $collectionConstraint
    );
}

私が理解している限り、制約は$form->bindRequest(...)または->bind(...)呼び出しでチェックされます。

だから、私のコントローラーに、私はこれをしました

public function insertAction(Request $request)
{
   if($request->getMethod() == 'POST'){
       $em = $this->getDoctrine()->getEntityManager();
       $user = $em->getRepository('SestanteUserBundle:User');
       $userObj = new User();
       $userObj->setSalt('prova');
       $parameters = $request->request->get('AddUser');
       $parameters['password'] = sha1($parameters['password']);
       $userObj->setGroups($em->getRepository('SestanteUserBundle:Groups')->find(3));
       $form = $this->createForm(new AddUserType(), $userObj);
       $logger = $this->get('logger');
       $logger->info('PROVA: '.gettype($parameters));
       $form->bind($parameters); /* al posto che fare un bind della form, faccio un bind normale con i parametri presi dalla post e modificati
                                 vedi la password che deve subire uno sha1 */
       $em->persist($userObj);
       $em->flush();
       return $this->redirect($this->generateUrl('SestanteUserBundle_homepage'));
   }

しかし、フォームを送信すると、このエラーに苦労する必要があります

配列型またはTraversableおよびArrayAccessの期待される引数、オブジェクトが指定されました

最も奇妙なことは、この操作に関係する2つのオブジェクト(bind引数とconstraintコレクション)のみが要求されたタイプであるということです。だから私はこれを追い抜く方法がわかりません。
何か案が?

4

1 に答える 1

3

次のようなもので試してください:

public function insertAction(Request $request)
{
    // First: Create you're object with only what you need
    $userObj = new User();

    // Then, build you're form
    $form = $this->createForm(new AddUserType(), $userObj);

    // Form submitted?
    if ($request->getMethod() == 'POST') {
        $request = $this->getRequest();
        $em = $this->getDoctrine()->getEntityManager();

        // Bind $request now !
        $form->bindRequest($request);

        // Your object is updated (not saved, ofc). You can now do what you want.
        $userObj->setPassword(sha1($user->getPassword());
        $userObj->setGroups($em->getRepository('SestanteUserBundle:Groups')->find(3));

        // Finish, save user
        $em->persist($userObj);
        $em->flush();

        return $this->redirect($this->generateUrl('SestanteUserBundle_homepage'));
    }
}

他のいくつかのこと:

  • フォームにidフィールドを入力する必要はありません。
  • おそらくsf2のセキュリティを確認する必要があります。コントローラでパスワードを手動でエンコードすることはお勧めできません。

編集:

validation_constraintオブジェクトを処理するフォームでオプションを使用できないため、この例外が発生しました。

このオプションは、データの配列でのみ使用できます。

于 2012-06-27T10:01:40.670 に答える