php バリデーション - Symfony2:カスタムコンパウンドフォームタイプでの制約の使い方




グループ validatevalue (3)

最初に検証に関するドキュメントをもう一度読むことをお勧めします。

このことから、検証は主にフォームタイプではなくクラスで行われるということです。 それはあなたが見落としたものです。 あなたがする必要があるのは次のとおりです:

  • たとえばsrc / My / Bundle / Form / Model / TextWithAutoValueという名前のTextWithAutoValueTypeのデータクラスを作成するには これには、 textcheckboxという名前のプロパティとsetters / getterが必要です。
  • このデータクラスをフォームタイプに関連付けるには そのためには、 TextWithAutoValueType :: getDefaultOptions()メソッドを作成し、 data_classオプションを設定する必要があります。 このメソッドの詳細については、 herehereしてください。
  • データクラスの検証を作成します。 これには注釈やResources / config / validation.ymlファイルを使用できます。 フォームのフィールドに制約を関連付ける代わりに、それらをクラスのプロパティに関連付ける必要があります。

validation.yml

src/My/Bundle/Form/Model/TextWithAutoValue:
    properties:
        text:
            - Type:
                type: string
            - NotBlank: ~
        checkbox:
            - Type:
                type: boolean

編集:

フォームタイプを別のフォームタイプで使用する方法をすでに知っていることを前提としています。 検証構成を定義するときに、 検証グループと呼ばれる非常に有用なものを使用できます。 ここでは、基本的な例( validation.ymlファイル内で、私は検証アノテーションにあまり慣れていないので):

src/My/Bundle/Form/Model/TextWithAutoValue:
    properties:
        text:
            - Type:
                type: string
                groups: [ Default, Create, Edit ]
            - NotBlank:
                groups: [ Edit ]
        checkbox:
            - Type:
                type: boolean

すべての制約に追加できるグループパラメータがあります。 これは、検証グループ名を含む配列です。 オブジェクトに対する検証を要求するときに、検証するグループのセットを指定できます。 システムは、検証ファイル内でどのような制約を適用すべきかを調べます。

デフォルトでは、「デフォルト」グループはすべての制約に設定されています。 これは、定期的な検証を実行するときに使用されるグループでもあります。

  • validation_groupsパラメータ(文字列の配列 - 検証グループの名前を設定することによって、 MyFormType :: getDefaultOptions()で特定のフォームタイプのデフォルトグループを指定することができます。
  • フォームタイプを別のフォームタイプに追加するときは、 MyFormType :: buildForm()で特定の検証グループを使用できます。

これは、もちろん、すべてのフォームタイプオプションの標準的な動作です。 例:

$formBuilder->add('auto_text', 'textWithAutoValue', array(
    'label' => 'my_label',
    'validation_groups' => array('Default', 'Edit'),
));

異なるエンティティの使用に関しては、積み上げられたフォームと同じアーキテクチャに従ってデータクラスを積み重ねることができます。 上記の例では、textWithAutoValueTypeを使用するフォームタイプは、 'auto_text'プロパティと対応するgetter / setterを持つdata_classを持つ必要があります。

検証ファイルでは、 有効な制約によって検証がカスケードできます。 Validを持つプロパティはプロパティのクラスを検出し、このクラスの対応する検証設定を見つけようとし、同じ検証グループを適用しようとします:

src/My/Bundle/Form/Model/ContainerDataClass:
    properties:
        auto_text:
            Valid: ~ # Will call the validation conf just below with the same groups

src/My/Bundle/Form/Model/TextWithAutoValue:
    properties:
        ... etc

ここで私は頭を壊していた質問が今ある。 私がSymfony2のエキスパートではないことを知ってください。だから私はどこかで新人ミスを犯したかもしれません。

Field1:標準のSymfony2 textフィールドタイプ

Field2:カスタムフィールドタイプcompoundフィールド( textフィールド+ checkboxフィールド)

私の目標: autoValue's text input child動作するように、 autoValueフィールドに制約を追加する

NotBlankが文字列値を期待しており、このフォームフィールドの内部データが配列array('input'=>'value', 'checkbox' => true)ため、制約が機能しない理由が考えられarray('input'=>'value', 'checkbox' => true) 。 この配列値は、カスタムのDataTransformerを使用して文字列に変換されます。 私はそれが既知の制約に対してフィールドを検証した後に起こると思う。

以下のコメント付きコードで見てきたように、テキスト入力に対して制約を働かせることができましたが、autoValueのフォームタイプにハードコードされている場合にのみ、メインフィールドの制約に対して検証したいと思います。

コントローラーとフィールドのサンプルコード:

コントローラコード

テスト用のクイックフォームの設定。

<?php
//...
// $entityInstance holds an entity that has it's own constraints 
// that have been added via annotations

$formBuilder = $this->createFormBuilder( $entityInstance, array(
    'attr' => array(
        // added to disable html5 validation
        'novalidate' => 'novalidate'
    )
));

$formBuilder->add('regular_text', 'text', array(
    'constraints' => array(
        new \Symfony\Component\Validator\Constraints\NotBlank()
    )
));

$formBuilder->add('auto_text', 'textWithAutoValue', array(
    'constraints' => array(
        new \Symfony\Component\Validator\Constraints\NotBlank()
    )
));

TextWithAutoValueソースファイル

src / My /コンポーネント/フォーム/タイプ/ TextWithAutoValueType.php

<?php

namespace My\Component\Form\Type;

use My\Component\Form\DataTransformer\TextWithAutoValueTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class TextWithAutoValueType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('value', 'text', array(
            // when I uncomment this, the NotBlank constraint works. I just
            // want to validate against whatever constraints are added to the
            // main form field 'auto_text' instead of hardcoding them here
            // 'constraints' => array(
            //     new \Symfony\Component\Validator\Constraints\NotBlank()
            // )
        ));

        $builder->add('checkbox', 'checkbox', array(
        ));

        $builder->addModelTransformer(
            new TextWithAutoValueTransformer()
        );
    }

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

src / My / Component / Form / DataTransformer / TextWithAutoValueType.php

<?php

namespace My\Component\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;

class TextWithAutoValueTransformer 
    implements DataTransformerInterface
{
    /**
     * @inheritdoc
     */
    public function transform($value)
    {
        return array(
            'value'    => (string) $value,
            'checkbox' => true
        );
    }

    /**
     * @inheritdoc
     */
    public function reverseTransform($value)
    {
        return $value['value'];
    }
}

src / My / ComponentBundle / Resources / config / services.yml

parameters:

services:
    my_component.form.type.textWithAutoValue:
        class: My\Component\Form\Type\TextWithAutoValueType
        tags:
            - { name: form.type, alias: textWithAutoValue }

src / My / ComponentBundle / Resources / views / Form / fields.html.twig

{% block textWithAutoValue_widget %}
    {% spaceless %}

    {{ form_widget(form.value) }}
    {{ form_widget(form.checkbox) }}
    <label for="{{ form.checkbox.vars.id}}">use default value</label>

    {% endspaceless %}
{% endblock %}

質問

私はかなり長い間、ドキュメントやGoogleを読んできており、このフォームを作成する際に追加された元の制約をコピー、バインド、または参照する方法を理解することはできません。

誰かこれを達成する方法を知っていますか?

- >ボーナスポイントの場合; メインフォームのバインドされたエンティティに追加された制約を有効にする方法 (エンティティクラスのアノテーションを介して)

PS

申し訳ありませんが、このような長い質問になったので、私は問題を明確にすることに成功したことを願っています。 そうでない場合は、私に詳細を問い合わせてください!


Bernhard Schussek(symofnyフォーム拡張の主な寄稿者)のhttps://speakerdeck.com/bschussek/3-steps-to-symfony2-form-mastery#39 (スライド39)に記載されているように、変圧器は決して情報を変更すべきではありませんその表現を変えるだけです。

情報を追加すると(チェックボックス=> true)、あなたは何か間違ったことをしています。

編集中:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('value', 'text', $options);

    $builder->add('checkbox', 'checkbox', array('mapped'=>false));

    $builder->addModelTransformer(
        new TextWithAutoValueTransformer()
    );
}

実際には: declare()ディレクティブを無視してください。 ごくまれにしか使用できないコードを実行しない限り、それが存在していたことを安全に忘れることができます。

それは、ここに詳細があると言われています。 declare()ディレクティブは現在2つの完全に無関係なものに使用されています:

  • declare(encoding=…)として、PHPファイルのエンコーディングを宣言します。 (この意味では、 <meta charset="…">サーバー側のバージョンと同等です)。

    しかし、これを使わないでください。 ほとんどの場合、スクリプトのエンコードは重要ではありません。 場合によっては、PHPのエンコーディングをzend.script_encoding設定値でグローバルに(うまくいけば "UTF-8"に)設定する必要があります。 それをファイルレベルで設定するのは混乱し、不要です。

  • declare(ticks=…) 、ティック関数が呼び出される頻度を定義します。 tick関数は、PHPインタプリタによって定期的に呼び出され、 register_tick_functionを使用して設定さregister_tick_functionます。

    php.netのコメントの中には、ネイティブ関数呼び出しでインタープリタがブロックされている間に、ティックが発生しないため、実際には期待通りに動作しないネットワークアクセスでタイムアウトを実装することを推奨しています。 ベンチマークではいくつかのアプリケーションがあるかもしれませんが、基本的に無用です。 私はそれを避けるだろう。





php symfony constraints symfony-forms symfony2.4