diff --git a/.travis.yml b/.travis.yml index ac47aae..6516bbc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: php php: - - 7.0 - + - 7.1 + - 7.2 + cache: directories: - vendor diff --git a/src/Instantiator/PropertyInstantiator.php b/src/Instantiator/PropertyInstantiator.php index a4a7569..d9a1fdc 100644 --- a/src/Instantiator/PropertyInstantiator.php +++ b/src/Instantiator/PropertyInstantiator.php @@ -8,8 +8,12 @@ class PropertyInstantiator implements InstantiatorInterface { - public function instantiate(string $class, array $data) + public function instantiate(string $class, ?array $data) { + if ($data === null) { + return null; + } + $object = new $class(); foreach ($data as $key => $value) { diff --git a/src/Node/BaseNode.php b/src/Node/BaseNode.php index c29c737..bde6b6c 100644 --- a/src/Node/BaseNode.php +++ b/src/Node/BaseNode.php @@ -225,12 +225,16 @@ public function getValue(string $field, $value) public function walk($input) { - $result = []; + if (!is_array($input)) { + return $input; + } if (!$this->hasChildren()) { return $input; } + $result = []; + foreach ($this->getChildren() as $field => $config) { if (!array_key_exists($field, $input)) { if ($config->isRequired()) { diff --git a/tests/InputHandlerTest.php b/tests/InputHandlerTest.php index dc21500..f6bb43a 100644 --- a/tests/InputHandlerTest.php +++ b/tests/InputHandlerTest.php @@ -99,6 +99,28 @@ public function define(): void } } +class TestNullableInputHandler extends InputHandler +{ + public function define(): void + { + $this->add('name', 'string'); + $this->add('address', 'string', ['allow_null' => true]); + } +} + +class TestNullableRecursiveInputHandler extends InputHandler +{ + public function define(): void + { + $this->add('type', 'string'); + $this->add('data', \stdClass::class, [ + 'handler' => new TestNullableInputHandler(), + 'instantiator' => new PropertyInstantiator(), + 'allow_null' => true, + ]); + } +} + class InputHandlerTest extends TestCase { public function testIsHandlingBasicInput(): void @@ -483,6 +505,40 @@ public function testDatetimeInvalidDatetimeInput($datetime): void $inputHandler->bind($input); $this->assertFalse($inputHandler->isValid()); } + + public function testIsHandlingInputWithNullValues(): void + { + $input = [ + 'type' => 'buyers', + 'data' => [ + 'name' => 'John Doe', + 'address' => null, + ], + ]; + + $inputHandler = new TestNullableRecursiveInputHandler(); + $inputHandler->bind($input); + + $this->assertTrue($inputHandler->isValid()); + + $data = $inputHandler->getData('data'); + + $this->assertNull($data->address); + + $input = [ + 'type' => 'buyers', + 'data' => null, + ]; + + $inputHandler = new TestNullableRecursiveInputHandler(); + $inputHandler->bind($input); + + $this->assertTrue($inputHandler->isValid()); + + $data = $inputHandler->getData('data'); + + $this->assertNull($data); + } } class TestConstraintOverrideType extends InputHandler