この投稿は Symfony 2.3 では最新ではありません
以下のコメントを読む
新バージョンが登場!
フォームでマップされていないフィールドを検証する (Symfony 2.1.2)
これは、フォーム内の無制限またはマップされていないフィールドを検証する現在の方法に関するいくつかのスタック オーバーフローの質問に対するグローバルな回答です。
豊富な Symfony 2 エコシステムにより、私たちが選んだフレームワークは急速に進化するツールになります。
Symfony 2.1 バージョンは、多くの非推奨をもたらします。これは、Symfony 2.0 から 2.1.2 で動作していたものが Symfony 2.3 では動作しなくなることを意味します。これに関する詳細については、UPGRADE FROM Symfony 2.0 から 2.1および Symfony コードの @deprecated コメントを参照してください。
非バインド フィールド
フォームを作成するとき、通常はエンティティを使用します。検証は、エンティティ自体で検証アノテーションに対して行うことができます。
namespace Dj\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Dj\TestBundle\Entity\Post
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
*/
class Post
{
// ... some code
/**
* @var string $title
* @ORM\Column(name="title", type="string", length=200, nullable=false)
* @Assert\NotBlank()
*/
private $title;
// .. getters and setters
}
ただし、モデルにマップされていないフィールドをフォームに挿入する必要がある場合があります (多くの場合)。
モデルの例は次のとおりです。
namespace Dj\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Dj\TestBundle\Entity\Post
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
*/
class Post
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**ghjkl
* @var string $title
* @ORM\Column(name="title", type="string", length=200, nullable=false)
* @Assert\NotBlank()
*/
private $title;
// ... getters and setters
}
フォームにmyExtraFieldという追加フィールドを追加する場合は、次のようにします。
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('title')
->add('myExtraField', 'choice', array(
'label' => 'myExtraField option :',
'choices' => array(
1 => 'Option One',
2 => 'Option Wat !'
),
'expanded' => true,
'mapped' => false
));
}
// other methods
}
ノート :
- mappingは、Symfony 2.3 で非推奨になるproperty_pathを置き換えます
- options 配列に'data' => 1エントリを追加することで、デフォルトで選択された値を myExtraField に追加できます。
コード例:
$builder->add('title')
->add('myExtraField', 'choice', array(
'label' => 'myExtraField option :',
'choices' => array(
1 => 'Option One',
2 => 'Option Wat !'
),
'data' => 1, // default selected option
'expanded' => true,
'mapped' => false
));
myExtraFieldフィールドを検証したい場合は、Post Entity アノテーションでは実行できません。フォームで実行する必要があります。
マッピングされていないフィールドの検証 - Symfony 2.0 のやり方
2.0 の方法は、バリデーターをフォームビルダーに追加することでした ($builder->addValidator(..)) が、この方法は非推奨です!
namespace Dj\TestBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
// needed namespaces for 2.0 validation
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormError;
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ... $builder->add()
// VALIDATING NON MAPPED FIELD Symfony 2.0 way
/** @var Symfony\Component\Form\CallbackValidator $myExtraFieldValidator **/
$myExtraFieldValidator = new CallbackValidator(function(FormInterface $form){
$myExtraField = $form->get('myExtraField')->getData();
if (empty($myExtraField)) {
$form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
}
});
// adding the validator to the FormBuilderInterface
$builder->addValidator($myExtraFieldValidator);
}
// ... other methods
}
これは現在、 myExtraField フィールドを検証していますが、$builder->addValidatorは Symfony 2.3 で機能しなくなります!
前方互換コード
UPGRADE FROM Symfony 2.0 to 2.1で述べたように、FormValidatorInterfaceは廃止されたため、検証クロージャ関数を FormEvents::POST_BIND イベントにバインドされたイベント リスナーに渡す必要があります。
これがコードです。
namespace Dj\TestBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
// needed namespaces for 2.1 validation
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormError;
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ... $builder->add()
// VALIDATING NON MAPPED FIELD Symfony 2.1.2 way (and forward)
/** @var \closure $myExtraFieldValidator **/
$myExtraFieldValidator = function(FormEvent $event){
$form = $event->getForm();
$myExtraField = $form->get('myExtraField')->getData();
if (empty($myExtraField)) {
$form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
}
};
// adding the validator to the FormBuilderInterface
$builder->addEventListener(FormEvents::POST_BIND, $myExtraFieldValidator);
}
// ... other methods
}
これは確かに Sf 専門家の助けを借りて改善できますが、今のところ、前方互換性のある方法でバインドされていないフォーム フィールドを検証します。
それが私たちの何人かを解放するのに役立つことを願っています.
デビッド