Skip to content

Commit 17c097b

Browse files
authored
Merge pull request #7 from moufmouf/intput_types_handing
Fixes handling of input types (that cannot be types)
2 parents ba00217 + 9893aa3 commit 17c097b

7 files changed

+61
-19
lines changed

src/ControllerQueryProvider.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private function getFieldsByAnnotations(string $annotationName): array
117117

118118
$phpdocType = $typeResolver->resolve((string) $refMethod->getReturnType());
119119

120-
$type = $this->mapType($phpdocType, $refMethod->getDocBlockReturnTypes(), $standardPhpMethod->getReturnType()->allowsNull());
120+
$type = $this->mapType($phpdocType, $refMethod->getDocBlockReturnTypes(), $standardPhpMethod->getReturnType()->allowsNull(), false);
121121

122122
$queryList[] = new QueryField($methodName, $type, $args, [$this->controller, $methodName], $this->hydrator);
123123
}
@@ -169,7 +169,7 @@ private function mapParameters(ReflectionMethod $refMethod, \ReflectionMethod $s
169169

170170
$phpdocType = $typeResolver->resolve((string) $parameter->getType());
171171

172-
$args[$parameter->getName()] = $this->mapType($phpdocType, $parameter->getDocBlockTypes(), $allowsNull);
172+
$args[$parameter->getName()] = $this->mapType($phpdocType, $parameter->getDocBlockTypes(), $allowsNull, true);
173173
}
174174

175175
return $args;
@@ -180,7 +180,7 @@ private function mapParameters(ReflectionMethod $refMethod, \ReflectionMethod $s
180180
* @param Type[] $docBlockTypes
181181
* @return TypeInterface
182182
*/
183-
private function mapType(Type $type, array $docBlockTypes, bool $isNullable): TypeInterface
183+
private function mapType(Type $type, array $docBlockTypes, bool $isNullable, bool $mapToInputType): TypeInterface
184184
{
185185
$graphQlType = null;
186186

@@ -194,14 +194,14 @@ private function mapType(Type $type, array $docBlockTypes, bool $isNullable): Ty
194194
// TODO: improve error message
195195
throw new GraphQLException("Don't know how to handle type ".((string) $type));
196196
} elseif (count($filteredDocBlockTypes) === 1) {
197-
$graphQlType = $this->toGraphQlType($filteredDocBlockTypes[0]);
197+
$graphQlType = $this->toGraphQlType($filteredDocBlockTypes[0], $mapToInputType);
198198
} else {
199199
throw new GraphQLException('Union types are not supported (yet)');
200200
//$graphQlTypes = array_map([$this, 'toGraphQlType'], $filteredDocBlockTypes);
201201
//$$graphQlType = new UnionType($graphQlTypes);
202202
}
203203
} else {
204-
$graphQlType = $this->toGraphQlType($type);
204+
$graphQlType = $this->toGraphQlType($type, $mapToInputType);
205205
}
206206

207207
if (!$isNullable) {
@@ -216,9 +216,10 @@ private function mapType(Type $type, array $docBlockTypes, bool $isNullable): Ty
216216
* Does not deal with nullable.
217217
*
218218
* @param Type $type
219+
* @param bool $mapToInputType
219220
* @return TypeInterface
220221
*/
221-
private function toGraphQlType(Type $type): TypeInterface
222+
private function toGraphQlType(Type $type, bool $mapToInputType): TypeInterface
222223
{
223224
if ($type instanceof Integer) {
224225
return new IntType();
@@ -236,9 +237,14 @@ private function toGraphQlType(Type $type): TypeInterface
236237
throw new GraphQLException('Type-hinting a parameter against DateTime is not allowed. Please use the DateTimeImmutable type instead.');
237238
}
238239

239-
return $this->typeMapper->mapClassToType(ltrim($type->getFqsen(), '\\'));
240+
$className = ltrim($type->getFqsen(), '\\');
241+
if ($mapToInputType) {
242+
return $this->typeMapper->mapClassToInputType($className);
243+
} else {
244+
return $this->typeMapper->mapClassToType($className);
245+
}
240246
} elseif ($type instanceof Array_) {
241-
return new ListType(new NonNullType($this->toGraphQlType($type->getValueType())));
247+
return new ListType(new NonNullType($this->toGraphQlType($type->getValueType(), $mapToInputType)));
242248
} else {
243249
throw new GraphQLException("Don't know how to handle type ".((string) $type));
244250
}

src/GraphQLException.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
namespace TheCodingMachine\GraphQL\Controllers;
55

6-
76
class GraphQLException extends \RuntimeException
87
{
9-
}
8+
}

src/QueryField.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ public function __construct(string $name, TypeInterface $type, array $arguments,
5050
$val = array_map(function ($item) use ($subtype) {
5151
if ($subtype instanceof DateTimeType) {
5252
return new \DateTimeImmutable($item);
53-
} elseif ($subtype->getKind() === TypeMap::KIND_OBJECT) {
53+
} elseif ($subtype->getKind() === TypeMap::KIND_INPUT_OBJECT) {
5454
return $this->hydrator->hydrate($item, $subtype);
5555
};
5656
return $item;
5757
}, $val);
5858
} elseif ($type instanceof DateTimeType) {
5959
$val = new \DateTimeImmutable($val);
60-
} elseif ($type->getKind() === TypeMap::KIND_OBJECT) {
60+
} elseif ($type->getKind() === TypeMap::KIND_INPUT_OBJECT) {
6161
$val = $this->hydrator->hydrate($val, $type);
6262
}
6363

src/TypeMapperInterface.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace TheCodingMachine\GraphQL\Controllers;
55

6+
use Youshido\GraphQL\Type\InputTypeInterface;
67
use Youshido\GraphQL\Type\TypeInterface;
78

89
/**
@@ -17,4 +18,12 @@ interface TypeMapperInterface
1718
* @return TypeInterface
1819
*/
1920
public function mapClassToType(string $className): TypeInterface;
21+
22+
/**
23+
* Maps a PHP fully qualified class name to a GraphQL input type.
24+
*
25+
* @param string $className
26+
* @return InputTypeInterface
27+
*/
28+
public function mapClassToInputType(string $className): InputTypeInterface;
2029
}

tests/AbstractQueryProviderTest.php

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@
33

44
namespace TheCodingMachine\GraphQL\Controllers;
55

6-
76
use PHPUnit\Framework\TestCase;
87
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject;
8+
use Youshido\GraphQL\Type\InputObject\InputObjectType;
9+
use Youshido\GraphQL\Type\InputTypeInterface;
910
use Youshido\GraphQL\Type\Object\ObjectType;
1011
use Youshido\GraphQL\Type\Scalar\StringType;
1112
use Youshido\GraphQL\Type\TypeInterface;
1213

1314
abstract class AbstractQueryProviderTest extends TestCase
1415
{
1516
private $testObjectType;
17+
private $inputTestObjectType;
1618
private $typeMapper;
1719
private $hydrator;
1820

@@ -29,18 +31,36 @@ protected function getTestObjectType()
2931
return $this->testObjectType;
3032
}
3133

34+
protected function getInputTestObjectType()
35+
{
36+
if ($this->inputTestObjectType === null) {
37+
$this->inputTestObjectType = new InputObjectType([
38+
'name' => 'TestObject',
39+
'fields' => [
40+
'test' => new StringType(),
41+
],
42+
]);
43+
}
44+
return $this->inputTestObjectType;
45+
}
46+
3247
protected function getTypeMapper()
3348
{
3449
if ($this->typeMapper === null) {
35-
$this->typeMapper = new class($this->getTestObjectType()) implements TypeMapperInterface {
50+
$this->typeMapper = new class($this->getTestObjectType(), $this->getInputTestObjectType()) implements TypeMapperInterface {
3651
/**
3752
* @var ObjectType
3853
*/
3954
private $testObjectType;
55+
/**
56+
* @var InputObjectType
57+
*/
58+
private $inputTestObjectType;
4059

41-
public function __construct(ObjectType $testObjectType)
60+
public function __construct(ObjectType $testObjectType, InputObjectType $inputTestObjectType)
4261
{
4362
$this->testObjectType = $testObjectType;
63+
$this->inputTestObjectType = $inputTestObjectType;
4464
}
4565

4666
public function mapClassToType(string $className): TypeInterface
@@ -51,6 +71,15 @@ public function mapClassToType(string $className): TypeInterface
5171
throw new \RuntimeException('Unexpected type');
5272
}
5373
}
74+
75+
public function mapClassToInputType(string $className): InputTypeInterface
76+
{
77+
if ($className === TestObject::class) {
78+
return $this->inputTestObjectType;
79+
} else {
80+
throw new \RuntimeException('Unexpected type');
81+
}
82+
}
5483
};
5584
}
5685
return $this->typeMapper;
@@ -68,4 +97,4 @@ public function hydrate(array $data, TypeInterface $type)
6897
}
6998
return $this->hydrator;
7099
}
71-
}
100+
}

tests/AggregateControllerQueryProviderTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace TheCodingMachine\GraphQL\Controllers;
44

5-
65
use Doctrine\Common\Annotations\AnnotationReader;
76
use PHPUnit\Framework\TestCase;
87
use Psr\Container\ContainerExceptionInterface;

tests/ControllerQueryProviderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthenticationService;
1010
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthorizationService;
1111
use Youshido\GraphQL\Execution\ResolveInfo;
12+
use Youshido\GraphQL\Type\InputObject\InputObjectType;
1213
use Youshido\GraphQL\Type\ListType\ListType;
1314
use Youshido\GraphQL\Type\NonNullType;
1415
use Youshido\GraphQL\Type\Object\ObjectType;
@@ -21,7 +22,6 @@
2122

2223
class ControllerQueryProviderTest extends AbstractQueryProviderTest
2324
{
24-
2525
public function testQueryProvider()
2626
{
2727
$controller = new TestController();
@@ -42,7 +42,7 @@ public function testQueryProvider()
4242
$this->assertInstanceOf(NonNullType::class, $usersQuery->getArgument('list')->getType());
4343
$this->assertInstanceOf(ListType::class, $usersQuery->getArgument('list')->getType()->getTypeOf());
4444
$this->assertInstanceOf(NonNullType::class, $usersQuery->getArgument('list')->getType()->getTypeOf()->getItemType());
45-
$this->assertInstanceOf(ObjectType::class, $usersQuery->getArgument('list')->getType()->getTypeOf()->getItemType()->getTypeOf());
45+
$this->assertInstanceOf(InputObjectType::class, $usersQuery->getArgument('list')->getType()->getTypeOf()->getItemType()->getTypeOf());
4646
$this->assertInstanceOf(BooleanType::class, $usersQuery->getArgument('boolean')->getType());
4747
$this->assertInstanceOf(FloatType::class, $usersQuery->getArgument('float')->getType());
4848
$this->assertInstanceOf(DateTimeType::class, $usersQuery->getArgument('dateTimeImmutable')->getType());

0 commit comments

Comments
 (0)