zendframework/zf2 — pull request #7056 by hschletz (2014-12-18 18:37:04+00:00)
Title: Refactoring and bugfixes for InputFilter component

This is a refactor of the InputFilter component that replaces PR #6784. It is based on the same fixes, but addresses all the issues discussed there, plus some more.

Validation (including evaluation of emptiness-related options) has been moved entirely from BaseInputFilter::validateInputs() to the Input classes' isValid() method. This has several advantages:

- Code is much simpler.
- Input classes are more self-contained. Special semantics (like FileInput with its reversed order of filtering and validation) are handled by the Input classes themselves without BaseInputFilter having to know about it. This would facilitate extending functionality by enabling Input classes with their own semantics regarding filtering, validation and definition of "empty". In fact, BaseInputFilter only iterates over the attached Input objects and calls their isValid() method - the implementation and interpretation of options are up the Input class.
- It's a requirement for fixing #6668.

When checking for empty input, each Input class implements its own definition for empty values:
- Input: NULL, '', array()
- ArrayInput: same as Input, applied to each element
- FileInput: Non-array values, file arrays with UPLOAD_ERR_NO_FILE

I added a lot of tests. Most tests simply enhance the existing test suite to ensure BC and will also pass with unpatched code. There are some exceptions:

- FileInputTest::testIsEmpty*() test a newly introduced auxiliary method.
- BaseInputFilterTest::testAllowEmptyTestsFilteredValueAndOverrulesValidatorChain() covers the scenario affected by #6668.
- InputTest::testValidatorInvokedIfValueIsEmptyAndAllowedAndContinue(), inherited by ArrayInputTest, revealed another bug that I fixed: ArrayInput injected the NotEmpty validator unconditionally, disregarding the continueIfEmpty() option. This bug could also be fixed separately.
- InputTest::testValidatorSkippedIfValueIsEmptyAndAllowedAndNotContinue() and InputTest::testAllowEmptyOptionSet() cover new functionality of the Input classes that was previously handled by BaseInputFilter.

The last one could be interpreted as BC break. It only affects code that uses an Input class directly, either by calling its isValid() method or by implementing one. Code that calls Input classes indirectly through the InputFilter class (the standard use case) is not affected.

I tested the code against an application that contains explicit workarounds for #6667 without regressions.