Skip to content

Commit d37fb34

Browse files
committed
Ability to define interface fields with closure
1 parent f548de5 commit d37fb34

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

src/Type/Definition/InterfaceType.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public static function addImplementationToInterfaces(ObjectType $impl)
4949
}
5050
}
5151

52+
/**
53+
* InterfaceType constructor.
54+
* @param array $config
55+
*/
5256
public function __construct(array $config)
5357
{
5458
Config::validate($config, [
@@ -63,7 +67,6 @@ public function __construct(array $config)
6367

6468
$this->name = $config['name'];
6569
$this->description = isset($config['description']) ? $config['description'] : null;
66-
$this->_fields = !empty($config['fields']) ? FieldDefinition::createMap($config['fields']) : [];
6770
$this->_resolveTypeFn = isset($config['resolveType']) ? $config['resolveType'] : null;
6871
$this->config = $config;
6972
}
@@ -73,11 +76,25 @@ public function __construct(array $config)
7376
*/
7477
public function getFields()
7578
{
79+
if (null === $this->_fields) {
80+
$this->_fields = [];
81+
$fields = isset($this->config['fields']) ? $this->config['fields'] : [];
82+
$fields = is_callable($fields) ? call_user_func($fields) : $fields;
83+
$this->_fields = FieldDefinition::createMap($fields);
84+
}
7685
return $this->_fields;
7786
}
7887

88+
/**
89+
* @param $name
90+
* @return FieldDefinition
91+
* @throws \Exception
92+
*/
7993
public function getField($name)
8094
{
95+
if (null === $this->_fields) {
96+
$this->getFields();
97+
}
8198
Utils::invariant(isset($this->_fields[$name]), 'Field "%s" is not defined for type "%s"', $name, $this->name);
8299
return $this->_fields[$name];
83100
}
@@ -90,6 +107,10 @@ public function getPossibleTypes()
90107
return $this->_implementations;
91108
}
92109

110+
/**
111+
* @param Type $type
112+
* @return bool
113+
*/
93114
public function isPossibleType(Type $type)
94115
{
95116
$possibleTypeNames = $this->_possibleTypeNames;

tests/Type/DefinitionTest.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,35 @@ public function testInputObjectTypeAllowsRecursiveDefinitions()
433433
$this->assertSame($inputObject, $schema->getType('InputObject'));
434434
$this->assertEquals(count($inputObject->getFields()), 2);
435435
$this->assertSame($inputObject->getField('nested')->getType(), $inputObject);
436-
$this->assertSame($inputObject->getField('value')->getType(), Type::string());
436+
}
437+
438+
public function testInterfaceTypeAllowsRecursiveDefinitions()
439+
{
440+
$called = false;
441+
$interface = new InterfaceType([
442+
'name' => 'SomeInterface',
443+
'fields' => function() use (&$interface, &$called) {
444+
$called = true;
445+
return [
446+
'value' => ['type' => Type::string()],
447+
'nested' => ['type' => $interface ]
448+
];
449+
}
450+
]);
451+
452+
$query = new ObjectType([
453+
'name' => 'Query',
454+
'fields' => [
455+
'test' => ['type' => $interface]
456+
]
457+
]);
458+
459+
$schema = new Schema($query);
460+
461+
$this->assertTrue($called);
462+
$this->assertSame($interface, $schema->getType('SomeInterface'));
463+
$this->assertEquals(count($interface->getFields()), 2);
464+
$this->assertSame($interface->getField('nested')->getType(), $interface);
465+
$this->assertSame($interface->getField('value')->getType(), Type::string());
437466
}
438467
}

0 commit comments

Comments
 (0)