オプションmapped
にfalse
を追加したフィールドが追加されたフォームがあります。しかし、フォームを検証しようとすると、これらの特定のフォームフィールドの上に「この値は無効です」ということを示すパスはありません。このオプションは検証をバイパスするものではありませんか?
これらのフォームフィールドは、他のフィールドにデータを入力する場合にのみ有用であり、保存する必要もチェックする必要もありません。
私が見つけた唯一の解決策は、送信ボタンをクリックするとjsですべての余分なフィールドを削除することです。
これは、フォーム内の無制限またはマップされていないフィールドを検証する現在の方法に関するいくつかのstackoverflow質問に対するグローバルな回答です。
豊富なSymfony 2エコシステムにより、選択のフレームワークは急速に進化するツールになります。
symfony 2.1バージョンでは、多くの廃止予定があります。これは、Symfony 2.0から2.1.2で動作しているものがSymfony 2.3で動作しなくなることを意味します。この詳細については、 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
}
注意 :
サンプルコード:
$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注釈では実行できません。フォームで実行する必要があります。
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フィールドを検証していますが、But$ builder-> addValidatorはSymfony 2.3で終了します!
Symfony 2.0から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の達人の助けを借りて改善できますが、現時点では、前方互換性のある方法で非バインドフォームフィールドを検証します。
それが私たちの一部を解き放つ助けになることを願っています.
デビッド
同様のトピックに関する質問で言及したように 、 Symfony 2.1以降では、 'constraints'オプションを使用して、マッピングされていないフィールドに検証を追加する必要があります:
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\NotBlank;
$builder
->add('firstName', 'text', array(
'constraints' => new MinLength(3),
))
->add('lastName', 'text', array(
'constraints' => array(
new NotBlank(),
new MinLength(3),
),
))
;
これで時間を失った私のような人を助けることを願っています...
already制約を使用している場合、これを行うことができます:
$builder
->add('new', 'repeated', array(
'type' => 'password',
'required' => true,
'invalid_message' => 'crmpicco.status.password_mismatch',
'constraints' => array(
new NotBlank(),
new Assert\Length([
'min' => 2,
'max' => 50,
'minMessage' => 'Your first name must be at least 2 characters long',
'maxMessage' => 'Your first name cannot be longer than 2 characters',
])
)
))
->add('save', 'submit', array(
'label' => 'password.form.fields.save',
))
;
マッピングされていないフィールドに基づくSymfony 3.4の式制約:
$resolver->setDefaults([
'data_class' => MyClass::class,
'constraints' => [
new Expression([
'expression' => 'this["endTime"].getData() >= this["startTime"].getData()',
'message' => 'L\'heure de fin doit être plus grande ou égale à l\'heure de début'
])
]
]);
うまくいきました。 symfony 2.1を確認しました。コードは次のようになります。
$builder->add('password', 'password', ['required' => false, 'mapped' => false]);
もちろん、プロパティ「必須」は不要です。 ドキュメントの例