2016-10-12 7 views
1

別のフィールドのカスタムコンストレイントにいくつかのフィールドの値を渡したいいくつかのフィールドを持つカスタムバリデータ)symfony(2.7) - >フォームを作成する - >フォームの別のフィールドからカスタムコンストレイントに値を渡す

フォーム:

... 
      ->add('BsaKey', new \app\...\fieldTypes\RadioButtonType(), [ 
       'choices' => [ 
        ... 
       ], 
       'expanded' => true, 
       'multiple' => false, 
       ... 
      ]) 
      ->add('MeteringCodes', 'collection', [ 
       'type' => new \app\...\formTypes\MeteringCodeType(), 
       'allow_add' => true, 
       'label' => false, 
       'options' => ['label' => $this->lang->get('MeteringCode.Caption')], 
       'constraints' => new \app\...\validators\NoIdenticMeteringCodes() 
      ]) 
... 

は、今私はMeteringCodeTypeのための私のカスタム制約にBsaKeyの値を渡す必要があります。

class MeteringCodeType extends \Symfony\Component\Form\AbstractType 
    { 
     public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, array $options) 
     { 
      $builder->add('meteringCode', 'text', [ 
        '...' => '...', 
        'constraints' => new \app\...\MeteringCodeConstraint(['param' => 'VALUE_OF_BsaKey']) 
      ]); 
     } 
    } 

どのように私はこれを達成することができますか?

P.S.私は...全体、ちょうどいくつかのスタンドアロンコンポーネントとしてのSymfonyを使用していない


EDIT:

class MeteringCodeValidator extends \Symfony\Component\Validator\ConstraintValidator 
{ 
    public function validate($value, \Symfony\Component\Validator\Constraint $constraint) 
    { 
     $BsaKey = $this->context->getRoot()->get('BsaKey')->getData(); 
     ... 
    } 
} 

から独立して動作するようです:

Thxを、私は解決策を見つけました"getTargets()"関数が返すオプションです。

答えて

0

custom constraintを使用してsimularを実行しました。 鉱山では、一方のフィールドが他方のフィールドよりも大きいかどうかがチェックされますので、自由に変更してください。

サンプルコード;

<?php 
// src/AppBundle/Validator/Constraints/FieldCompare.php 
namespace AppBundle\Validator\Constraints; 

use Symfony\Component\Validator\Constraint; 

/** 
* @Annotation 
*/ 
class FieldCompare extends Constraint 
{ 
    /** 
    * Error Message 
    * @access public 
    * @var string - with placeholders [field1,field2] 
    */ 
    public $message = 'Field field2 must be greater than field1 '; 

    /** 
    * Form fields 
    * @access public 
    * @var array 
    */ 
    public $fields = array(); 

    /** 
    * Class accessors (getters) for the fields. 
    * @access public 
    * @var array 
    */ 
    public $properties = array(); 

    /** 
    * Error Path 
    * @var string 
    */ 
    public $errorPath; 

    public function __construct($options = null) 
    { 
     parent::__construct($options); 

     // check fields is an array 
     if (!is_array($this->fields) && !is_string($this->fields)) { 
      throw new UnexpectedTypeException($this->fields, 'array'); 
     } 

     // make sure there are two of them 
     if (2 != count($this->fields)) { 
      throw new ConstraintDefinitionException("Two fields must be specified."); 
     } 

     // make sure they are strings 
     foreach ($this->fields as $f) { 
      if (null !== $this->errorPath && !is_int()) { 
       throw new UnexpectedTypeException($this->errorPath, 'integer or null'); 
      } 
     } 
    } 

    /** 
    * getTargets() 
    * 
    * Set traget (so can be used against the class). 
    * @access public 
    * @return type 
    */ 
    public function getTargets() 
    { 
     return self::CLASS_CONSTRAINT; 
    } 
} 

<?php 
// src/AppBundle/Validator/Constraints/FieldCompareValidator.php 
namespace AppBundle\Validator\Constraints; 

use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\ConstraintValidator; 

class FieldCompareValidator extends ConstraintValidator { 

    public function validate($protocol, Constraint $constraint) 
    { 
     $fields = (array) $constraint->fields; 
     $properties = (array) $constraint->properties; 

     if ($protocol->$properties[0]() >= $protocol->$properties[1]()) { 
      $this->context->addViolationAt($fields[1], $constraint->message, 
        array(
         'field1' => $this->prettyField($fields[0]), 
         'field2' => $this->prettyField($fields[1]) 
        ), null); 
     } 
    } 

    private function prettyField($field) 
    { 
     if (strstr($field, '_')) { 
      $pretty = str_replace('_', ' ', $field); 
     } else { 
      // is camelCase 
      $converted = preg_replace('/(?!^)[[:upper:]]+/',' \0', $field); 
      if (is_array($converted)) { 
       $pretty = implode(' ', $converted); 
      } else { 
       $pretty = $converted; 
      } 
     } 
     return ucwords($pretty); 
    } 
} 

ここでは、バリデータ(yaml形式)の使用方法を示します。

AppBundle\Model\Foo: 
    constraints: 
     - AppBundle\Validator\Constraints\FieldCompare: 
      fields: [min_lead_time, max_lead_time] 
      properties: [getminLeadtime, getmaxLeadtime] 
      groups: [add] 
+0

"validate"関数がコンテキストクラス(現在の文字列値ではないもの)を返すようにしようとしましたが、うまくいきませんでした。 –

+0

改行をしてmsgを送信しようとしましたが、私は "getTargets()"を使ってオブジェクトを "validate()" - funcktionの最初の引数として取得しようとしました。 –

関連する問題