diff --git a/CHANGELOG.md b/CHANGELOG.md index d9c8c054..1a4613d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,12 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed +- [#163](https://github.com/zendframework/zend-inputfilter/pull/163) adds code to `BaseInputFilter::populate()` to detect non-iterable, + non-null values passed as a value for a composed input filter. Previously, these would trigger + an exception; they now instead result in an empty array being used to populate the + input filter, which will generally result in invalidation without causing an + exception. + - [#162](https://github.com/zendframework/zend-inputfilter/pull/162) fixes incorrect abstract service factory registration in `ConfigProvider`as per the [latest documentation](https://docs.zendframework.com/zend-inputfilter/specs/#setup). In particular, it ensures that the `InputFilterAbstractFactory` is registered under the `input_filters` configuration instead of the diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 10aff0d3..124a16b3 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -523,6 +523,11 @@ protected function populate() $value = $this->data[$name]; if ($input instanceof InputFilterInterface) { + // Fixes #159 + if (! is_array($value) && ! $value instanceof Traversable) { + $value = []; + } + $input->setData($value); continue; } diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 1685020b..829c82d6 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -585,6 +585,24 @@ public function testMerge() ); } + public function testNestedInputFilterShouldAllowNonArrayValueForData() + { + $filter1 = new BaseInputFilter(); + $nestedFilter = new BaseInputFilter(); + $nestedFilter->add(new Input('nestedField1')); + $filter1->add($nestedFilter, 'nested'); + + // non scalar and non null value + $filter1->setData(['nested' => false]); + self::assertNull($filter1->getValues()['nested']['nestedField1']); + + $filter1->setData(['nested' => 123]); + self::assertNull($filter1->getValues()['nested']['nestedField1']); + + $filter1->setData(['nested' => new stdClass()]); + self::assertNull($filter1->getValues()['nested']['nestedField1']); + } + public function addMethodArgumentsProvider() { $inputTypes = $this->inputProvider(); diff --git a/test/InputFilterTest.php b/test/InputFilterTest.php index fd1e9d81..16a45b6c 100644 --- a/test/InputFilterTest.php +++ b/test/InputFilterTest.php @@ -11,6 +11,7 @@ use ArrayIterator; use PHPUnit_Framework_MockObject_MockObject as MockObject; +use stdClass; use Zend\InputFilter\Factory; use Zend\InputFilter\Input; use Zend\InputFilter\InputFilter;