2013-07-08 84 views
16

如何設置依賴於其他輸入字段的輸入過濾器。 我想驗證'apDepTime'字段是否超過'apArrTime'。zf2驗證:我如何驗證相關字段?

我該如何處理zf2?

我還想指出,我正在使用'日期驗證程序'。

請幫助我的人。

FlightDataForm.php

<?php 

namespace FcFlight\Form; 

use Zend\Form\Form; 
use Zend\Form\Element; 

class FlightDataForm extends Form 
{ 
/** 
* @var string 
*/ 
protected $_formName = 'flightData'; 

/** 
* @param null $name 
* @param array $options 
*/ 
public function __construct($name = null) 
{ 
    if (!is_null($name)) { 
     $this->_formName = $name; 
    } 

    parent::__construct($this->_formName); 

    //Fieldset Ap Dep 
    $this->add(array(
     'name'   => 'apDep', 
     'type'   => 'Zend\Form\Fieldset', 
     'options'  => array(
      'legend'  => 'App Dep', 
     ), 
     'elements'  => array(
      array(
       'spec' => array(
        'name' => 'apDepTime', 
        'type' => 'Zend\Form\Element\Text', 
        'attributes' => array(
         'required' => true, 
         'maxlength' => '5', 
         'id' => 'apDepTime', 
        ), 
        'options' => array(
         'label' => 'Time', 
         'hint' => 'HH:MM', 
         'description' => 'UTC', 
        ), 
       ), 
      ), 
     ), 
    )); 

    //Fieldset Ap Arr 
    $this->add(array(
     'name'   => 'apArr', 
     'type'   => 'Zend\Form\Fieldset', 
     'options'  => array(
      'legend'  => 'App Arr', 
     ), 
     'elements'  => array(
      //apArrTime 
      array(
       'spec' => array(
        'name' => 'apArrTime', 
        'type' => 'Zend\Form\Element\Text', 
        'attributes' => array(
         'required' => true, 
         'maxlength' => '5', 
         'id' => 'apArrTime', 
        ), 
        'options' => array(
         'label' => 'Time', 
         'hint' => 'HH:MM', 
         'description' => 'UTC', 
        ), 
       ), 
      ), 
     ), 
    )); 

    $this->add(new Element\Csrf('csrf')); 

    //Submit button 
    $this->add(array(
     'name' => 'submitBtn', 
     'attributes' => array(
      'type' => 'submit', 
      'value' => 'Add', 
     ), 
    )); 

} 
} 

FlightDataFilter.php

<?php 
namespace FcFlight\Filter; 

use Zend\InputFilter\Factory as InputFactory; 
use Zend\InputFilter\InputFilter; 
use Zend\InputFilter\InputFilterAwareInterface; 
use Zend\InputFilter\InputFilterInterface; 
use Zend\Db\Adapter\Adapter; 

class FlightDataFilter implements InputFilterAwareInterface 
{ 

/** 
* @var $inputFilter 
*/ 
protected $inputFilter; 

/** 
* @var $dbAdapter 
*/ 
protected $dbAdapter; 

/** 
* @var string 
*/ 
protected $table = ''; 

public $apDepTime; 
public $apArrTime; 

/** 
* @param \Zend\Db\Adapter\Adapter $dbAdapter 
*/ 
public function __construct(Adapter $dbAdapter) 
{ 
    $this->dbAdapter = $dbAdapter; 
} 

/** 
* @return \Zend\Db\Adapter\Adapter 
*/ 
public function getDbAdapter() 
{ 
    return $this->dbAdapter; 
} 

/** 
* Array to Object 
* 
* @param array $data 
*/ 
public function exchangeArray(array $data) 
{ 
    $this->apDepTime = (isset($data['apDep']['apDepTime'])) ? $data['apDep']['apDepTime'] : null; 
    $this->apArrTime = (isset($data['apArr']['apArrTime'])) ? $data['apArr']['apArrTime'] : null; 
} 

/** 
* @return array 
*/ 
public function getArrayCopy() 
{ 
    return get_object_vars($this); 
} 

/** 
* @param InputFilterInterface $inputFilter 
* @return void|InputFilterAwareInterface 
* @throws \Exception 
*/ 
public function setInputFilter(InputFilterInterface $inputFilter) 
{ 
    throw new \Exception("Not used"); 
} 


/** 
* @return \Zend\InputFilter\InputFilter|\Zend\InputFilter\InputFilterInterface 
*/ 
public function getInputFilter() 
{ 
    if (!$this->inputFilter) { 

     $inputFilter = new InputFilter(); 
     $factory = new InputFactory(); 

     $flightNumberInputFilter = new InputFilter(); 

     $flightNumberInputFilter->add($factory->createInput(array(
      'name' => 'flightNumberIdIcao', 
      'required' => true, 
     ))); 

     $apDepInputFilter = new InputFilter(); 

     $apDepInputFilter->add($factory->createInput(array(
      'name' => 'apDepTime', 
      'required' => true, 
      'validators' => array(
       array(
        'name' => 'Date', 
        'options' => array(
         'format' => 'H:i', 
        ), 
       ), 
      ), 
     ))); 

     $inputFilter->add($apDepInputFilter, 'apDep'); 

     $apArrInputFilter = new InputFilter(); 

     $apArrInputFilter->add($factory->createInput(array(
      'name' => 'apArrTime', 
      'required' => true, 
      'validators' => array(
       array(
        'name' => 'Date', 
        'options' => array(
         'format' => 'H:i', 
        ), 
       ), 
       array(
        'name' => 'Callback', 
        'options' => array(
         'messages' => array(
          \Zend\Validator\Callback::INVALID_VALUE => 'The arrival time is less than the departure time', 
         ), 
         'callback' => function($value, $context = array()) { 
          // value of this input 
          $apArrTime = \DateTime::createFromFormat('H:i', $value); 
          // value of input to check against from context 
          $apDepTime = \DateTime::createFromFormat('H:i', $context['apDepTime']); 
          // compare times, eg.. 
          return $apDepTime > $apArrTime; 
         }, 
        ), 
       ), 
      ), 
     ))); 

     $inputFilter->add($apArrInputFilter, 'apArr'); 

     $this->inputFilter = $inputFilter; 
    } 

    return $this->inputFilter; 
} 
} 

回答

29

可以使用Zend\Validator\Callback驗證此

的第一個參數傳遞給你的回調是價值應用驗證器的輸入。

第二個參數是由輸入名稱鍵入的其他表單值的數組,代表您想要比較值的上下文。

舉一個簡單的例子...

$apArrInputFilter->add($factory->createInput(array(
     'name' => 'apArrTime', 
     'required' => true, 
     'validators' => array(
       array(
        'name' => 'Callback', 
        'options' => array(
         'messages' => array(
          \Zend\Validator\Callback::INVALID_VALUE => 'The departure time is less than the arrival time', 
         ), 
         'callback' => function($value, $context=array()) { 
          // value of this input 
          $apArrTime = $value; 
          // value of input to check against from context 
          $apDepTime = $context['apDepTime']; 
          // compare times, eg.. 
          $isValid = $apDepTime > $apArrTime; 
          return $isValid; 
         }, 
        ), 
       ), 
     ), 
    ))); 

顯然,你需要編寫代碼,以您的需求爲實際日期比較,但應該讓你開始。

+0

酥。非常感謝你。我是ZF的新手。你的解決方案幫了我很多。 但我的代碼沒有看到$ context ['apDepTime'],因爲apDepTime是在一個不同的InputFilter($ apDepInputFilter)中,我無法在匿名函數中看到$ this。 –

+0

我使用您的決定更新了我的代碼。左邊想着如何獲得apDepTime的值。 –

0

您也可以使用不同的方法。美國一個InputFilter來定義你自己的isValid()函數。

告訴你表單使用InputFilter。

$this->setInputFilter(new Filter\MyFilter()); 

執行您自己的isValid()函數。

namespace Application\Form\Filter; 

use Zend\InputFilter\InputFilter; 
use Zend\Validator; 
use Zend\Filter; 

class MyFilter extends InputFilter 
{ 
    public function isValid($context = null) 
    { 
     // add your dependent validation 
    } 

    public function __construct() 
    { 
     // Add youre form field validations 
    } 

http://theabstract.de/zf2-dynamic-form-validation/