Zend Framework 2, filter a value after validation in an InputFilter

1.8k Views Asked by At

In an InputFilter I have this code:

    $password = new Input('password');
    $password->setRequired(false)
             ->getValidatorChain()
             ->attach(new Validator\StringLength(6));

    $password->getFilterChain()
             ->attach($this->passwordHash);

The problem is that the filter is applying to the value before the validation, so the validator always returns true.

I was wondering if there is any way to do the filtering after the validation.

2

There are 2 best solutions below

2
Kwido On

It seems odd to filter after validation as the input before validation could be edited by the filters. Like strip tags or trim the string. If you do use a filter like \Zend\I18n\Filter\Alnum() you could let it remove the whitespaces. So see it as bad practice to filter after validating your input.

E.g., take those filters:

// Default settings, deny whitespace
$filter = new \Zend\I18n\Filter\Alnum();
echo $filter->filter("This is (my) content: 123");
// Returns "Thisismycontent123"

// First param in constructor is $allowWhiteSpace
$filter = new \Zend\I18n\Filter\Alnum(true);
echo $filter->filter("This is (my) content: 123");
// Returns "This is my content 123"

Notice that the begin value differs from the result. But you can filter after validation, but I guess you have to it by yourself. So you could add a method to your inputfilter or form which you call after validation. For example:

public function filterPassword() {
    $filter = new \Zend\I18n\Filter\Alnum(true);
    $inputs = $this->getInputs();
    $password = $filter->filter($inputs['password']);
    return $password;
}

In your controller you can do this for example:

public function ExampleController extends AbstractActionController
{
    public function sampleAction() {
        $form = new LoginForm();
        if($form->isValid()) {
            $inputFilter = $form->getInputFilter();
            $filterdPassword = $inputFilter->filterPassword();
        }
        return array('form' => $form);
    }
}
0
Wilt On

Zend\InputFilter\FileInput class is one of the input types that does validation before filtering. You can see how they solved it in the source code and make your own PasswordInput class based on that solution.

As you can see in the source code on line 64 there is an if clause that prevents the filters to run as long as isValid is false (the initial value). So the validators run first and then when the parent InputFilter after validation calls getValue again to get the value from FileInput it runs the filters.