2012-11-07 12 views
6

私はユーザー登録のためのフォームを持ち、ユーザー名フィールドのみがフォームにあります。私の形式では、ユーザー入力だけを許可したいと考えています。 Nicenameは登録時のユーザー名と同じになります。フォームに存在しないエンティティのフィールドの妥当性確認

このフォームはつまり、私のフォームタイプのクラスで、Userエンティティにバインドされます。ユーザ名とnicenameの両方に設定されNotBlank制約があり

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'Some\Bundle\Entity\User', 
    )); 
} 

エンティティユーザー、。私は、検証すなわち$form->isValid()にユーザー名のみではなくnicenameでフォームを、ビルドする場合

namespace Some\Bundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Constraints; 

//... 

class User 
{ 
    //... 

    /** 
    * @var string $username 
    * 
    * @ORM\Column(name="user_login", type="string", length=60, unique=true) 
    * @Constraints\NotBlank() 
    */ 
    private $username; 

    /** 
    * @var string $nicename 
    * 
    * @ORM\Column(name="user_nicename", type="string", length=64) 
    * @Constraints\NotBlank() 
    */ 
    private $nicename; 

    //... 

しかし、それは検証に失敗しました。

namespace Some\Bundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Some\Bundle\Form\Type\RegisterType; 
//... 

class UserController extends Controller 
{ 
    //... 
public function registerAction() 
{ 
    //... 
    $request = $this->getRequest(); 
    $form = $this->createForm(new RegisterType()); 

    if ($request->getMethod() == 'POST') { 
     // force set nicename to username. 
     $registerFields = $request->request->get('register'); 
     $registerFields['nicename'] = $registerFields['username']; 
     $request->request->set('register', $registerFields); 

     $form->bind($request); 

     if ($form->isValid()) { 
      $user = $form->getData(); 
      //persist $user, etc... 

とフォームタイプで、私は私のbuildForm方法にこれを追加します:

$builder->add('nicename', 'hidden'); 

しかし、私はこの非常に洗練見つける、一部を残して、次の

これを回避するには、私が思い付きます(要求オブジェクトから抽出し、データを入れ、それを要求オブジェクトに戻すなど)、生成されたHTMLのソースコードを検査する場合は、隠されたフィールドを見ることができます。

少なくとも、フォームタイプを使用するコントローラは、エンティティの制約を保持しながら、上記のようなことをする必要はありませんか?

私はUserエンティティをバックアップするテーブルスキーマを変更できません。私はNotBlank制約を維持したいと思います。


EDIT:長い口論の後、私は、検証グループを使用することを決定し、それが働きました。

class User 
{ 
//... 

/** 
* @var string $username 
* 
* @ORM\Column(name="user_login", type="string", length=60, unique=true) 
* @Constraints\NotBlank(groups={"register", "edit"}) 
*/ 
private $username; 

/** 
* @var string $nicename 
* 
* @ORM\Column(name="user_nicename", type="string", length=64) 
* @Constraints\NotBlank(groups={"edit"}) 
*/ 
private $nicename; 

フォームタイプ:

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'Some\Bundle\Entity\User', 
     'validation_groups' => array('register', 'Default') 
    )); 
} 

'Default'が必要か、それは私がフォームタイプbuildForm方法で追加されたすべての他の制約を無視していることを...あなたの心、その場合は、機密:'default'は動作しません。

私が持続する場合、私は私のコントローラでこれを行う必要があるので、しかし、私は、(私は私の元の質問に入れていなかったと残念に)十分ではないことを見つける:

$user->setNicename($user->getUsername()); 

として、

$builder->addEventSubscriber(new RegisterPostBindListener($builder->getFormFactory())); 

そしてRegisterPostBindListen:ボーナス、Iは、フォームタイプbuildForm方法でForm Event Subscriber

を追加することによって、タイプ準位を形成するために、コントローラからこれを移動させますあなたがNULL可能とすることができるフィールド伝えることができ、あなたのUserエンティティでERクラス

<?php 
namespace Some\Bundle\Form\EventListener; 

use Symfony\Component\Form\Event\DataEvent; 
use Symfony\Component\Form\FormFactoryInterface; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Form\FormEvents; 

class RegisterPostBindListener implements EventSubscriberInterface 
{ 

public function __construct(FormFactoryInterface $factory) 
{ 

} 

public static function getSubscribedEvents() 
{ 
    return array(FormEvents::POST_BIND => 'setNames'); 
} 

public function setNames(DataEvent $event) 
{ 
    $data = $event->getData(); 

    $data->setNicename($data->getUsername()); 
} 
} 

答えて

0

/** 
*@ORM\Column(type="string", length=100, nullable=TRUE) 
*/ 
protected $someVar; 

あなたのビューコントローラは何もする必要はありませんこの方法です。

忘れてください。また、あなたのnicename変数を初期化PrePersist条件を定義することができます

// you need to first tell your User entity class it has LifeCycleCallBacks: 

/** 
* @ORM\Entity() 
* @ORM\HasLifecycleCallbacks() 
*/ 
class User 
{ 

    ... 

    /** 
    *@ORM\PrePersist 
    */ 
    public function cloneName() 
    { 
     $this->nicename = $this->username; 
    } 
} 
+0

このエンティティはスキーマが変更できないテーブルに基づいているため、nullableを設定できません。 ...もちろん私は可能性がありますが、私はSQLエラーを持続させるリスクがあります。 – luiges90

+0

エンティティの__construct()関数で、NULLエラーを防ぐためにエンティティにいくつかのデフォルト値を与えることができます。 – Zhang

+0

実体のNotBlank Constraintを実際に保持したいと思います。私はあなたの方法を使ってみましたが、フィールドに '@Constraints \ NotBlank()'がなければ動作します。 – luiges90

0

この場合、Callbackアサーションを使用してカスタム検証ルールを作成する必要があります。

関連する問題