2010-03-06 34 views
13

Tôi có hai trường trong Biểu mẫu Zend và tôi muốn áp dụng quy tắc xác thực để đảm bảo người dùng nhập một trong hai trường này.Trình xác thực biểu mẫu Zend: Phần tử A hoặc phần tử B

$companyname = new Zend_Form_Element_Text('companyname'); 
    $companyname->setLabel('Company Name'); 
    $companyname->setDecorators($decors); 
    $this->addElement($companyname); 

    $companyother = new Zend_Form_Element_Text('companyother'); 
    $companyother->setLabel('Company Other'); 
    $companyother->setDecorators($decors); 
    $this->addElement($companyother); 

Làm cách nào để thêm trình xác thực sẽ xem xét cả hai trường?

Trả lời

12

Xem 'Lưu ý: Ngữ cảnh xác thực' tại số page này. Zend_Form chuyển ngữ cảnh này đến mọi Zend_Form_Element :: isValid gọi làm tham số thứ hai. Vì vậy, chỉ cần viết trình xác thực của riêng bạn để phân tích ngữ cảnh.

EDIT:
Được rồi, tôi nghĩ tôi sẽ tự mình chụp. Nó không được thử nghiệm, cũng không phải là một phương tiện cho tất cả các kết thúc, nhưng nó sẽ cho bạn một ý tưởng cơ bản.

class My_Validator_OneFieldShouldBePresent extend Zend_Validator_Abstract 
{ 
    const NOT_PRESENT = 'notPresent'; 

    protected $_messageTemplates = array(
     self::NOT_PRESENT => 'Field %field% is not present' 
    ); 

    protected $_messageVariables = array(
     'field' => '_field' 
    ); 

    protected $_field; 

    protected $_listOfFields; 

    public function __construct(array $listOfFields) 
    { 
     $this->_listOfFields = $listOfFields; 
    } 

    public function isValid($value, $context = null) 
    { 
     if(!is_array($context)) 
     { 
      $this->_error(self::NOT_PRESENT); 

      return false; 
     } 

     foreach($this->_listOfFields as $field) 
     { 
      if(isset($context[ $field ])) 
      { 
       return true; 
      } 
     } 

     $this->_field = $field; 
     $this->_error(self::NOT_PRESENT); 

     return false; 
    } 
} 

Cách sử dụng:

$oneOfTheseFieldsShouldBePresent = array('companyname', 'companyother'); 

$companyname = new Zend_Form_Element_Text('companyname'); 
$companyname->setLabel('Company Name'); 
$companyname->setDecorators($decors); 
$companyname->addValidator(new My_Validator_OneFieldShouldBePresent($oneOfTheseFieldsShouldBePresent)); 
$this->addElement($companyname); 

$companyother = new Zend_Form_Element_Text('companyother'); 
$companyother->setLabel('Company Other'); 
$companyother->setDecorators($decors); 
$companyname->addValidator(new My_Validator_OneFieldShouldBePresent($oneOfTheseFieldsShouldBePresent)); 
$this->addElement($companyother); 
0

Tôi chưa từng gặp một giải pháp như vậy, nhưng nó hoàn toàn hợp lệ để +1.

Tôi sẽ mở rộng Your_Form::isValid() để bao gồm kiểm tra thủ công các giá trị của hai yếu tố đó.

Nếu tất cả các trường vượt qua trình xác thực cá nhân của riêng mình, xác thực này có thể thuộc về dạng toàn bộ và có thể được đặt vào xác thực biểu mẫu thay vì các trường. Bạn có đồng ý với dòng suy nghĩ này không?

0

Tôi đồng ý với @chelmertz rằng một tính năng như thế này không tồn tại.

Điều tôi không đồng ý là mở rộng Your_Form::isValid(). Thay vào đó, tôi muốn write a custom Validator chấp nhận các giá trị của cả hai phần tử biểu mẫu phải có giá trị. Bằng cách này tôi có thể tái sử dụng nó trên các yếu tố hình thức tùy ý. Điều này có phần tương tự với Trình xác thực hợp lệ.

1

Các giải pháp được cung cấp bởi @fireeyedboy là tiện dụng nhưng không làm việc cho vấn đề này chính xác.

Zend_Validate_Abstract đang sử dụng ngữ cảnh không được chuyển thành biến số isValid(). Bằng cách này, khi sử dụng phương pháp isValid() (bất kể trường hợp ban đầu hoặc ghi đè) các trường trống không được chuyển qua và xác thực (trừ khi bạn có setRequired(true) hoặc setAllowEmpty(false), mà chúng tôi không muốn). Vì vậy, trong trường hợp khi bạn để cả hai trường (companynamecompanyother) trống, sẽ không có hành động nào diễn ra. Giải pháp duy nhất mà tôi biết là mở rộng lớp Zend_Validate để cho phép các trường trống được xác thực.

Vui lòng cho tôi biết nếu bạn biết giải pháp tốt hơn vì tôi đang gặp khó khăn với vấn đề tương tự.

Các vấn đề liên quan