Skip to content

Commit b890ef7

Browse files
committed
Ability to define InputObjectType fields with closure (#22)
1 parent cc6c6a1 commit b890ef7

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

src/Type/Definition/InputObjectType.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
<?php
22
namespace GraphQL\Type\Definition;
33

4+
use GraphQL\Utils;
5+
46
class InputObjectType extends Type implements InputType
57
{
68
/**
79
* @var array<InputObjectField>
810
*/
9-
private $_fields = [];
11+
private $_fields;
12+
13+
public $config;
1014

1115
public function __construct(array $config)
1216
{
@@ -21,12 +25,7 @@ public function __construct(array $config)
2125
'description' => Config::STRING
2226
]);
2327

24-
if (!empty($config['fields'])) {
25-
foreach ($config['fields'] as $name => $field) {
26-
$this->_fields[$name] = new InputObjectField($field + ['name' => $name]);
27-
}
28-
}
29-
28+
$this->config = $config;
3029
$this->name = $config['name'];
3130
$this->description = isset($config['description']) ? $config['description'] : null;
3231
}
@@ -36,6 +35,29 @@ public function __construct(array $config)
3635
*/
3736
public function getFields()
3837
{
38+
if (null === $this->_fields) {
39+
$this->_fields = [];
40+
$fields = isset($this->config['fields']) ? $this->config['fields'] : [];
41+
$fields = is_callable($fields) ? call_user_func($fields) : $fields;
42+
foreach ($fields as $name => $field) {
43+
$this->_fields[$name] = new InputObjectField($field + ['name' => $name]);
44+
}
45+
}
46+
3947
return $this->_fields;
4048
}
49+
50+
/**
51+
* @param string $name
52+
* @return InputObjectField
53+
* @throws \Exception
54+
*/
55+
public function getField($name)
56+
{
57+
if (null === $this->_fields) {
58+
$this->getFields();
59+
}
60+
Utils::invariant(isset($this->_fields[$name]), "Field '%s' is not defined for type '%s'", $name, $this->name);
61+
return $this->_fields[$name];
62+
}
4163
}

tests/Type/DefinitionTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,37 @@ public function testAllowsRecursiveDefinitions()
402402

403403
$this->assertNotNull($blog->getField('owner'));
404404
$this->assertSame($user, $blog->getField('owner')->getType()->getWrappedType(true));
405+
}
406+
407+
public function testInputObjectTypeAllowsRecursiveDefinitions()
408+
{
409+
$called = false;
410+
$inputObject = new InputObjectType([
411+
'name' => 'InputObject',
412+
'fields' => function() use (&$inputObject, &$called) {
413+
$called = true;
414+
return [
415+
'value' => ['type' => Type::string()],
416+
'nested' => ['type' => $inputObject ]
417+
];
418+
}
419+
]);
420+
$someMutation = new ObjectType([
421+
'name' => 'SomeMutation',
422+
'fields' => [
423+
'mutateSomething' => [
424+
'type' => $this->blogArticle,
425+
'args' => ['input' => ['type' => $inputObject]]
426+
]
427+
]
428+
]);
405429

430+
$schema = new Schema($this->blogQuery, $someMutation);
431+
432+
$this->assertTrue($called);
433+
$this->assertSame($inputObject, $schema->getType('InputObject'));
434+
$this->assertEquals(count($inputObject->getFields()), 2);
435+
$this->assertSame($inputObject->getField('nested')->getType(), $inputObject);
436+
$this->assertSame($inputObject->getField('value')->getType(), Type::string());
406437
}
407438
}

0 commit comments

Comments
 (0)