From af5c515116d0c42f2e757f2bf1e183f81dfe3250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 18 Oct 2018 12:31:28 +0200 Subject: [PATCH] Adding the ability to case SourceFields to ID type --- src/Annotations/SourceField.php | 17 +++++++++++++++++ src/Annotations/SourceFieldInterface.php | 7 +++++++ src/ControllerQueryProvider.php | 7 ++++++- src/Registry/Registry.php | 6 ------ tests/ControllerQueryProviderTest.php | 13 +++++++++++++ tests/Fixtures/TestTypeId.php | 15 +++++++++++++++ 6 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 tests/Fixtures/TestTypeId.php diff --git a/src/Annotations/SourceField.php b/src/Annotations/SourceField.php index bc44e29..6505a05 100644 --- a/src/Annotations/SourceField.php +++ b/src/Annotations/SourceField.php @@ -13,6 +13,7 @@ * @Attribute("logged", type = "bool"), * @Attribute("right", type = "TheCodingMachine\GraphQL\Controllers\Annotations\Right"), * @Attribute("returnType", type = "string"), + * @Attribute("isId", type = "bool"), * }) */ class SourceField implements SourceFieldInterface @@ -37,6 +38,11 @@ class SourceField implements SourceFieldInterface */ private $returnType; + /** + * @var bool + */ + private $id; + /** * @param mixed[] $attributes */ @@ -46,6 +52,7 @@ public function __construct(array $attributes = []) $this->logged = $attributes['logged'] ?? false; $this->right = $attributes['right'] ?? null; $this->returnType = $attributes['returnType'] ?? null; + $this->id = $attributes['isId'] ?? false; } /** @@ -87,4 +94,14 @@ public function getReturnType(): ?string { return $this->returnType; } + + /** + * If the GraphQL type is "ID", isID will return true. + * + * @return bool + */ + public function isId(): bool + { + return $this->id; + } } diff --git a/src/Annotations/SourceFieldInterface.php b/src/Annotations/SourceFieldInterface.php index f0461ed..4244e1f 100644 --- a/src/Annotations/SourceFieldInterface.php +++ b/src/Annotations/SourceFieldInterface.php @@ -35,4 +35,11 @@ public function isLogged(): bool; * @return string|null */ public function getReturnType(): ?string; + + /** + * If the GraphQL type is "ID", isID will return true. + * + * @return bool + */ + public function isId(): bool; } diff --git a/src/ControllerQueryProvider.php b/src/ControllerQueryProvider.php index 284bea6..014c88d 100644 --- a/src/ControllerQueryProvider.php +++ b/src/ControllerQueryProvider.php @@ -283,7 +283,12 @@ private function getSourceFields(): array $phpdocType = $typeResolver->resolve((string) $refMethod->getReturnType()); - if ($sourceField->getReturnType()) { + if ($sourceField->isId()) { + $type = GraphQLType::id(); + if (!$refMethod->getReturnType()->allowsNull()) { + $type = GraphQLType::nonNull($type); + } + } elseif ($sourceField->getReturnType()) { $type = $this->registry->get($sourceField->getReturnType()); } else { $docBlockReturnType = $this->getDocBlocReturnType($docBlockObj, $refMethod); diff --git a/src/Registry/Registry.php b/src/Registry/Registry.php index de0d99d..3946d35 100644 --- a/src/Registry/Registry.php +++ b/src/Registry/Registry.php @@ -86,12 +86,6 @@ public function get($id) } // The registry will try to instantiate the type if the class exists and has an annotation. - - - /*if (is_a($id, ObjectType::class, true)) { - $this->values[$id] = new $id($this); - return $this->values[$id]; - }*/ if ($this->isGraphqlType($id)) { $refTypeClass = new \ReflectionClass($id); if ($refTypeClass->hasMethod('__construct') && $refTypeClass->getMethod('__construct')->getNumberOfRequiredParameters() > 0) { diff --git a/tests/ControllerQueryProviderTest.php b/tests/ControllerQueryProviderTest.php index 6d94931..50c4200 100644 --- a/tests/ControllerQueryProviderTest.php +++ b/tests/ControllerQueryProviderTest.php @@ -5,6 +5,7 @@ use Doctrine\Common\Annotations\AnnotationReader; use GraphQL\Type\Definition\BooleanType; use GraphQL\Type\Definition\FloatType; +use GraphQL\Type\Definition\IDType; use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\IntType; use GraphQL\Type\Definition\ListOfType; @@ -14,6 +15,7 @@ use TheCodingMachine\GraphQL\Controllers\Fixtures\TestController; use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject; use TheCodingMachine\GraphQL\Controllers\Fixtures\TestType; +use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeId; use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingAnnotation; use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingField; use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeWithSourceFieldInterface; @@ -220,6 +222,17 @@ public function testSourceFieldDoesNotExists() $queryProvider->getFields(); } + public function testSourceFieldIsId() + { + $queryProvider = new ControllerQueryProvider(new TestTypeId(), $this->getRegistry()); + $fields = $queryProvider->getFields(); + $this->assertCount(1, $fields); + + $this->assertSame('test', $fields[0]->name); + $this->assertInstanceOf(NonNull::class, $fields[0]->getType()); + $this->assertInstanceOf(IDType::class, $fields[0]->getType()->getWrappedType()); + } + public function testFromSourceFieldsInterface() { $registry = new Registry(new EmptyContainer(), diff --git a/tests/Fixtures/TestTypeId.php b/tests/Fixtures/TestTypeId.php new file mode 100644 index 0000000..be6e479 --- /dev/null +++ b/tests/Fixtures/TestTypeId.php @@ -0,0 +1,15 @@ +