2011-01-28 6 views
6

요소가 있습니다. 사용자 지정 유효성 검사기와 사용자 지정 필터를 추가하고 싶습니다. validator는, 입력이 몇개인가의 값의 1 개 (살)인지를 확인한 다음, 필터는 입력에 custom value를 추가합니다. 즉, 필터를 실행하기 전에 원래 입력을 확인해야합니다. 나는이 순서대로 행한다.이 Validator 다음에이 필터를 실행하는 방법

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

그러나이 순서는 존중되지 않는다. 필터가 먼저 실행되고 데이터가 변경되면 유효성 검사기는 필터링 된 데이터에서 실행되므로 유효한 입력에 대해서도 항상 실패합니다. 그것은이 의도적

주입니다 documentation에서 보인다 검증 필터링 값에서 작동 Zend_Form_Element :: isValid() 검증 이전에 제공된 필터 체인을 통해 필터 값. 자세한 내용은 필터 섹션을 참조하십시오.

어떻게 유효성 검사기와 필터가 실행되는 순서를 지정할 수 있습니까?

답변

7

물론 유효성 검사 후 필터링을 지원하는 사용자 지정 요소를 만드는 것처럼 보일 것입니다.- 얇은 컨트롤러를 유지

$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(), 
    ), 
)); 

이는 형태로 검증 및 필터링을 유지 :

/** 
* 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; 
    } 
} 

사용법은 다음과 같이 될 것이다 :이 방법에 대해.

테스트되지 않았지만 어둠 속에서만 찌르다. 그리고 분명히 키를 사용하여 필터를 추가/제거하기 위해 API를 늘리거나 수정할 수 있습니다.

Whaddya는 생각하십니까?

+0

+1. 아주 좋아 보인다. 또한 setPostValidateFilters() 메서드가 'postValidateFilters'키에 대해 자동으로 (예?) 호출된다는 것을 알지 못했습니다. – Marcin

+0

@Marcin : 옵션이 작동하는 방식이라고 생각합니다. 옵션 이름과 "일치"하는 메소드가 있다면, 그 메소드는'setOptions()'중에 호출된다. –

+0

+1 매우 좋은 구현 – tawfekov

4

필터를 전혀 추가하지 않았을 수 있습니다. 컨트롤러에 먼저 내용의 유효성을 검사 한 다음 별도로 필터를 사용

$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 
} 

나는이 해본 적이 없다,하지만 난이 (또는 비슷한)이 작동하지 않을 수 있습니다 가정합니다.

+0

+1 가능한 해결책이지만 확실하지는 않습니다. 다른 모든 방법으로 문제가 해결되면 해보 겠지만 제어기를 얇게 유지하고 양식 요소가 속한 필터링 논리를 유지하는 것이 좋습니다. – jblue

+0

물론 폼 코드에도 그대로 두길 원하지만 유효성 검사기와 필터가 호출되는 순서에 영향을주는 다른 방법은 생각할 수 없습니다. 가끔 컨트롤러에 물건을 추가하는 것도 좋을 것입니다. 예를 들어, 뭔가 다른 필드를 검사하거나 채우는 경우에만 필드 집합이 필요할 때가 있습니다. 클라이언트 측에서 또는 사용자가 양식을 작성하기 전에 안정적으로 확인할 수 없으므로 제어기에서 추가 양식 마법을 수행하는 것이 필요하거나 그렇지 않은 경우가 있습니다. ( – mingos

1

좋은 점! ,

AFAIK 필터 또는 입력을 확인하기 전에 실행해야한다 : 에

그것은 종종 유용 및/또는 필요의 ZF docs의 사전 검증에 입력 일부 정상화를 수행합니다. 예를 들어, 은 모든 HTML을 제거 할 수 있지만 은 제출이 유효한지 확인하기 위해 으로 남아있는 내용에 대한 유효성 검사를 실행합니다. 또는 공백을 줄여서 StringLength 유효성 검사기가 공백 문자 공백 문자없이 숫자 입력의 올바른 길이 인 을 사용할 수 있습니다.

하지만 만약 당신이

+0

일부 결함은 필터라고 생각합니다. 매우 복잡하고 입력을 무효로 만들 수있는 수정을합니다. 따라서 필터는 유효성 검사 전에 실행해야하는 트림과 더 복잡한 수정을하는 다른 필터로 언급되는 정규화 필터와 2 가지 유형으로 나뉩니다. 이 필터를 트리거 할 때 필터를 추가 할 때 선택하십시오 – jblue

1

는 당신이 달성하고자하는 텍스트 요소가 처리되는 방식의 기본 동작을 변경하는 것입니다 도움을해야합니다 mingos의 답변을 해결할 수없는 경우에있는 경우에만. 따라서 Zend_Form_Element_Text를 확장하고 isValid() 메소드를 오버로드하는 고유 한 요소 (예 : My_Form_Element_Text)를 만들 수 있다고 생각합니다.

특히 원래 isValid() 메소드의 두 번째 행을 $value = $this->getValue();에서 $value = $this->getUnfilteredValue();으로 변경할 수 있습니다. 이렇게하면 필터링되지 않은 값을 사용하여 유효성 검사가 수행됩니다.

+0

이것은 재미있는 생각입니다. 내가보기에는 다른 모든 필터가 자동으로 상실된다는 것입니다. 필터링되지 않은 값을 수정하면 손실됩니다. 예를 들어 트림 필터 (Trim filter). 이런 이유로, mingo의 대답은 컨트롤러에있는 것이 맘에 들지 않지만 원하는 효과를 줄 것입니다. r은 그가 유효성 검사기와 필터에 대해 원하는 정확한 순서를 지정할 수 있습니다. – jblue

+0

@jblue. 따라서 유효성 검사 후에 하나의 필터 만 적용하고 나머지는 정상적인 방법으로 적용하려고합니다. 그렇습니까? 이것은 물론 사용자 정의 텍스트 요소를 작성하여 수행 할 수 있습니다. – Marcin