2011-01-28 16 views
6

Tôi có một phần tử. Tôi muốn thêm trình xác thực tùy chỉnh và bộ lọc tùy chỉnh cho nó. Trình xác thực đảm bảo đầu vào là một trong nhiều giá trị được phép, sau đó bộ lọc thêm một số giá trị tùy chỉnh vào đầu vào. Điều này có nghĩa là tôi phải xác thực đầu vào gốc trước tiên trước khi chạy bộ lọc. Tôi làm theo thứ tự nàyCách làm cho Bộ lọc này chạy sau khi Trình xác thực này

$element = new Zend_Form_Element_Text('element'); 
$element->addValidator('PermittedValue', false); 
$element->addFilter('TotalHyphen', false); 
$this->addElement($element); 

nhưng thứ tự này không được tôn trọng. Bộ lọc chạy đầu tiên và thay đổi dữ liệu, sau đó trình xác thực chạy trên dữ liệu được lọc có nghĩa là bộ lọc luôn thất bại ngay cả đối với đầu vào hợp lệ. Có vẻ như từ documentation rằng đây là cố ý

Lưu ý: Validation hoạt động trên được lọc Values ​​Zend_Form_Element :: isValid() lọc các giá trị thông qua việc cung cấp chuỗi lọc trước khi xác nhận. Xem phần Bộ lọc để biết thêm thông tin .

Làm cách nào để xác định thứ tự bộ kiểm tra và bộ lọc chạy?

Trả lời

7

Chắc chắn có vẻ như việc tạo phần tử tùy chỉnh hỗ trợ lọc sau xác thực sẽ là cách để thực hiện.Làm thế nào về điều này:

/** 
* An element that supports post-validation filtering 
*/ 
class My_Form_Element_PostValidateFilterable extends Zend_Form_Element_Text 
{ 
    protected $_postValidateFilters = array(); 

    public function setPostValidateFilters(array $filters) 
    { 
     $this->_postValidateFilters = $filters; 
     return $this; 
    } 

    public function getPostValidateFilters() 
    { 
     return $this->_postValidateFilters; 
    } 

    public function isValid($value, $context = null) 
    { 
     $isValid = parent::isValid($value, $context); 
     if ($isValid){ 
      foreach ($this->getPostValidateFilters() as $filter){ 
       $value = $filter->filter($value); 
      } 
      $this->setValue($value); 
     } 
     return $isValid; 
    } 
} 

Cách sử dụng sẽ là một cái gì đó như thế này:

$elt = $form->addElement('PostValidateFilterable', 'myElement', array(
    'label' => 'MyLabel', 
    'filters' => array(
     'StringTrim', 
     // etc 
    ), 
    'validators' => array(
     'NotEmpty', 
     // etc 
    ), 
    // here comes the good stuff 
    'postValidateFilters' => array(
     new My_Filter_RunAfterValidateOne(), 
     new My_Filter_RunAfterValidateTwo(), 
    ), 
)); 

Điều này sẽ giúp xác nhận và lọc theo hình thức - giữ bộ điều khiển mỏng.

Không được thử nghiệm, chỉ là đâm trong bóng tối. Và chắc chắn bạn có thể vỗ/sửa đổi API để thêm/xóa bộ lọc theo khóa, v.v.

Whaddya nghĩ sao?

+0

+1. Trông rất đẹp. Tôi cũng không biết rằng phương thức setPostValidateFilters() sẽ được gọi tự động (yes?) Cho khóa 'postValidateFilters'. – Marcin

+0

@Marcin: Tôi nghĩ đó là cách các tùy chọn hoạt động. Nếu có một phương thức "khớp" với tên tùy chọn, thì phương thức đó sẽ được gọi trong 'setOptions()'. –

+0

+1 triển khai rất đẹp – tawfekov

4

Có thể không thêm bộ lọc. Xác nhận các nội dung đầu tiên trong bộ điều khiển, và sau đó sử dụng các bộ lọc riêng biệt:

$request = $this->getRequest(); 
if ($request->isPost() && $form->isValid($request->getParams())) { 
    $filter = new Filter_Whatever(); 
    $val = $filter->filter($request->getParam('element')); 
    ... //call your model or whatever 
} 

Tôi chưa bao giờ làm điều này, nhưng tôi cho rằng điều này (hoặc một cái gì đó tương tự) có thể làm việc.

+0

+1 Đó là giải pháp khả thi, nhưng không chắc tôi thích nó. Tôi sẽ làm điều đó nếu tất cả đều thất bại, nhưng tôi muốn giữ cho bộ điều khiển mỏng và giữ logic lọc với phần tử biểu mẫu mà nó thuộc về. – jblue

+0

Chắc chắn, tôi cũng muốn giữ nó trong mã biểu mẫu, nhưng tôi không thể nghĩ ra bất kỳ cách nào khác ảnh hưởng đến thứ tự mà trong đó trình xác thực và bộ lọc được gọi. Đôi khi tôi thêm công cụ vào bộ điều khiển cũng như lý tưởng nên cư trú trong biểu mẫu, ví dụ, khi một tập hợp các trường được yêu cầu nếu và chỉ khi một cái gì đó khác được kiểm tra/điền. Bạn không thể kiểm tra chắc chắn rằng ở phía máy khách hoặc trước khi người dùng điền vào biểu mẫu, do đó, thực hiện một số phép thuật dạng bổ sung trong bộ điều khiển đôi khi cần thiết, như nó hay không: ( – mingos

1

Điểm tốt! ,

lọc AFAIK nên hoặc phải chạy trước khi xác nhận đầu vào: từ ZF docs

Nó thường hữu ích và/hoặc cần thiết để thực hiện một số bình thường trên đầu vào trước khi xác nhận. Ví dụ: bạn có thể muốn loại bỏ tất cả HTML, nhưng chạy xác thực của bạn về những gì còn lại để đảm bảo việc gửi là hợp lệ. Hoặc bạn có thể muốn cắt không gian trống đầu vào xung quanh sao cho Trình xác thực chuỗi thời gian sẽ sử dụng độ dài chính xác của đầu vào mà không cần đếm các ký tự khoảng trắng đầu hoặc cuối .

nhưng khi và chỉ khi bạn đang ở trong trường hợp này không thể giải quyết câu trả lời mingos của phải sự giúp đỡ

+0

Tôi nghĩ đó là một lỗi thiết kế. rất phức tạp và chúng thực hiện các sửa đổi có thể làm cho đầu vào không hợp lệ. Vì vậy, bộ lọc nên được chia thành 2 loại. chọn khi thêm bộ lọc khi kích hoạt bộ lọc này – jblue

1

gì bạn muốn đạt được là thay đổi hành vi mặc định như thế nào yếu tố văn bản đang được xử lý. Do đó, tôi nghĩ bạn có thể tạo phần tử của riêng mình (ví dụ: My_Form_Element_Text) mở rộng Zend_Form_Element_Text và quá tải phương thức isValid() của nó.

Cụ thể là bạn chỉ có thể thay đổi dòng thứ hai trong phương thức isValid() ban đầu, từ $value = $this->getValue(); thành $value = $this->getUnfilteredValue();. Bằng cách này, quá trình xác thực của bạn sẽ được thực hiện bằng cách sử dụng các giá trị chưa được lọc.

+0

Đây là một ý tưởng thú vị Vấn đề duy nhất tôi thấy với nó là tôi sẽ tự động mất tất cả các bộ lọc khác.Nếu tôi thực hiện sửa đổi trên giá trị chưa lọc thì tôi sẽ mất bộ lọc Trim chẳng hạn, vì lý do này, cho đến nay câu trả lời của mingo có thể mang lại cho tôi hiệu quả mong muốn mặc dù tôi không thích nó nằm trong bộ điều khiển. r có thể chỉ định thứ tự chính xác mà anh ta muốn cho trình xác thực và bộ lọc. – jblue

+0

@jblue. Vì vậy, bạn chỉ muốn có một bộ lọc được áp dụng sau khi xác thực và phần còn lại theo cách thông thường, phải không? Điều này tất nhiên vẫn có thể được thực hiện bằng cách làm cho phần tử văn bản tùy chỉnh của bạn. – Marcin

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