diff --git a/src/InputQuery.php b/src/InputQuery.php index 096f9e3..d1e683a 100644 --- a/src/InputQuery.php +++ b/src/InputQuery.php @@ -263,6 +263,18 @@ private function resolveObjectType(ReflectionParameter $param, array $query, arr return $arrayObjectResult; } + // Check if the parameter name exists as a direct nested array in query + if (array_key_exists($paramName, $query) && is_array($query[$paramName])) { + // This should never fail as $className comes from ReflectionParameter type info + assert(class_exists($className), "Internal logic error: Class '$className' from reflection should exist"); + + /** @var Query $nestedQuery */ + $nestedQuery = $query[$paramName]; + + /** @var class-string $className */ + return $this->newInstance($className, $nestedQuery); + } + // Regular object type with #[Input] - create nested $nestedQuery = $this->extractNestedQuery($paramName, $query); diff --git a/tests/InputQueryTest.php b/tests/InputQueryTest.php index 979ff8a..5f3c5ae 100644 --- a/tests/InputQueryTest.php +++ b/tests/InputQueryTest.php @@ -118,6 +118,26 @@ public function testCreateNestedObject(): void $this->assertSame('john@example.com', $todo->author->email); } + public function testCreateBracketObject(): void + { + $query = [ + 'title' => 'Buy milk', + 'author' => [ + 'name' => 'John', + 'email' => 'john@example.com', + ], + ]; + + $todo = $this->inputQuery->newInstance(TodoInput::class, $query); + + $this->assertInstanceOf(TodoInput::class, $todo); + /** @var TodoInput $todo */ + $this->assertSame('Buy milk', $todo->title); + $this->assertInstanceOf(AuthorInput::class, $todo->author); + $this->assertSame('John', $todo->author->name); + $this->assertSame('john@example.com', $todo->author->email); + } + public function testCreateMixedInputAndDI(): void { $query = [