1

私は Symfony 初心者で、フォーム フィールドまたは別のフィールドに基づいてフォーム フィールドを検証する最善の方法を視覚化しようとして失敗しました。ケース: フォームは、生年月日または年齢のいずれかを要求します。生年月日が入力されている場合、年齢は無視されます。age が入力され、dob が空の場合、dob は今日の日付から年数を引いたものと言われます。どちらも入力されていない場合、検証エラーがスローされます。私はこれを Smarty 検証で達成しました。学習課題として、Symfony でアプリケーションを再現しようとしています。

両方のフィールドがエンティティのプロパティであるこのソリューションを見てきました。私の場合、年齢はありません。そのため、そのソリューションをどのように適用するかは明確ではありません。ポインタをいただければ幸いです。

ありがとう。

ジョージ PS: (編集: dreck を削除) PPS: (編集: ほぼ動作するバージョンのためのスペースを作るために削除) フォーム:

// src\Mana\AdminBundle\Resources\views\Form\Type\NewClientType.php
namespace Mana\AdminBundle\Form\Type;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Mana\AdminBundle\Validator\Constraints;

class NewClientType extends AbstractType {

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array('validation_groups' => 'client_new', 
            'validation_constraint' => new DOBorAge(),
            ));
     }

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('fname', null, array('required' => false));
        $builder->add('sname', null, array('required' => false));
        $builder->add('dob', 'birthday', array('widget' => 'single_text', 'required' => false));
        $builder->add('age', null, array('mapped' => false, 'required' => false));
    }

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

サービス:

services:
  client_new:
    class: Mana\AdminBundle\Validator\Constraints\DOBorAgeValidator
    scope: request
    tags:
      - { name: validator.constraint_validator, alias: dobage_validator}

バリデーター:

// src\Mana\AdminBundle\Form\Type\DOBorAge.php
namespace Mana\AdminBundle\Form\Type;
use Mana\AdminBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

class DOBorAge extends Constraint {

    public $message = 'Either a date of birth or age must be present';

    public function validatedBy() {
        return 'dobage_validator';
    }

    public function getTargets() {
        return Constraint::CLASS_CONSTRAINT;
    }

}

// src\Mana\AdminBundle\Validator\Constraints\DOBorAgeValidator.php
namespace Mana\AdminBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class DOBorAgeValidator extends ConstraintValidator {

    protected $request;

    public function __construct(Request $request) {
        $this->request = $request;
    }

    public function validate($value, Constraint $constraint) {
        var_dump($this->request->request->get('client'));
        die();
        return true;
    }
}
4

2 に答える 2

1

この種の検証を管理する最善の方法は、カスタマイズされた検証制約をフォームに追加することだと思います。

メソッドを拡張Symfony\Component\Validator\Constraintしてオーバーライドするクラスを追加するだけです。validatedBy()次に、フォーム検証のすべてのロジックが含まれるように、作成する必要があるカスタマイズされたバリデーターを指定できます。

このカスタマイズされたバリデーターは、Symfony\Component\Validator\ConstraintValidatorクラスを拡張isValid()し、Symfony 2.0.x のメソッドまたはvalidate()Symfony 2.1.xのメソッドを実装する必要があります。

次に、値を確認して比較し、このメソッド内で必要なことを行い、検証ルールの 1 つまたは多くが尊重されない場合は最終的に違反を追加します。

2 つのフィールドに基づく Symfony2 検証も確認してください。

于 2012-11-14T20:25:15.740 に答える
1

Symfony 風のソリューション: 日付または年齢のいずれかを取得し、エントリを日付に変換する単一のフォーム フィールド。(さて、これをカスタムフィールドに変えることさえできれば...)

namespace Mana\AdminBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Mana\AdminBundle\Form\DataTransformer\AgeToDOB;

class NewClientType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $transformer = new AgeToDOB();

        $builder->add('fname', null, array('required' => false, 
            'invalid_message' => 'First name not be blank',));
        $builder->add('sname', null, array('required' => false,
            'invalid_message' => 'Last name not be blank',));
        $builder->add(
                $builder->create('dob', 'text', array('required' => false,
            ))->addModelTransformer($transformer));
    }

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

そして変圧器:

namespace Mana\AdminBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Mana\AdminBundle\Entity\Client;

class AgeToDOB implements DataTransformerInterface {

    public function reverseTransform($dob) {

        if (null == $dob) {
            return '';
        }
        if ((substr_count($dob, '/') == 2 && strtotime($dob))) {
            $date = new \DateTime($dob);
            return date_format($date, 'Y-m-d');
        }
        if (is_numeric($dob)) {
            $date = new \DateTime();
            $interval = 'P' . $dob . 'Y';
            $date->sub(new \DateInterval($interval));
            return date_format($date, 'Y-m-d');
        }
    }

    public function transform($client) {
        if (null == $client) {
            return '';
        }
        if (is_object($client)) {
            $dob = $client->getDob();
            // date: test for two / characters
            if ((substr_count($dob, '/') == 2 && strtotime($dob))) {
                $date = new \DateTime($dob);
                return date_format($date, 'm/d/Y');
            }
            if (is_numeric($dob)) {
                $date = new \DateTime();
                $interval = 'P' . $dob . 'Y';
                $date->sub(new \DateInterval($interval));
                return date_format($date, 'm/d/Y');
            }
        }
    }

}
于 2012-11-23T14:44:28.887 に答える