From a33b559f32b8f5e53d66ff4d235925430ea4274b Mon Sep 17 00:00:00 2001 From: Olexandr Grynchuk Date: Fri, 8 Mar 2024 10:10:09 +0200 Subject: [PATCH 1/7] Fix prefetching the same GQL type for batch request --- src/PrefetchBuffer.php | 65 ++++++++++++------ src/QueryField.php | 10 +-- .../Controllers/CompanyController.php | 17 +++++ .../Controllers/ContactController.php | 12 ++++ tests/Fixtures/Integration/Models/Company.php | 18 +++++ .../Integration/Types/CompanyType.php | 43 ++++++++++++ .../Integration/Types/ContactType.php | 49 +++++++++++++ tests/Fixtures/Integration/Types/PostType.php | 31 +++++++++ tests/Integration/EndToEndTest.php | 68 +++++++++++++++++++ tests/SchemaFactoryTest.php | 8 +++ 10 files changed, 295 insertions(+), 26 deletions(-) create mode 100644 tests/Fixtures/Integration/Controllers/CompanyController.php create mode 100644 tests/Fixtures/Integration/Models/Company.php create mode 100644 tests/Fixtures/Integration/Types/CompanyType.php create mode 100644 tests/Fixtures/Integration/Types/PostType.php diff --git a/src/PrefetchBuffer.php b/src/PrefetchBuffer.php index 5105d02249..fe3db2afa2 100644 --- a/src/PrefetchBuffer.php +++ b/src/PrefetchBuffer.php @@ -4,6 +4,7 @@ namespace TheCodingMachine\GraphQLite; +use GraphQL\Type\Definition\ResolveInfo; use function array_key_exists; use function md5; use function serialize; @@ -20,15 +21,26 @@ class PrefetchBuffer private array $results = []; /** @param array $arguments The input arguments passed from GraphQL to the field. */ - public function register(object $object, array $arguments): void - { - $this->objects[$this->computeHash($arguments)][] = $object; + public function register( + object $object, + array $arguments, + ?ResolveInfo $info = null + ): void { + $this->objects[$this->computeHash($arguments, $info)][] = $object; } /** @param array $arguments The input arguments passed from GraphQL to the field. */ - private function computeHash(array $arguments): string - { - return md5(serialize($arguments)); + private function computeHash( + array $arguments, + ?ResolveInfo $info = null + ): string { + if ( + null === $info + || null === ($queryBody = $info->operation->loc?->source->body) + ) { + return md5(serialize($arguments)); + } + return md5(serialize($arguments) . $queryBody); } /** @@ -36,32 +48,43 @@ private function computeHash(array $arguments): string * * @return array */ - public function getObjectsByArguments(array $arguments): array - { - return $this->objects[$this->computeHash($arguments)] ?? []; + public function getObjectsByArguments( + array $arguments, + ?ResolveInfo $info = null + ): array { + return $this->objects[$this->computeHash($arguments, $info)] ?? []; } /** @param array $arguments The input arguments passed from GraphQL to the field. */ - public function purge(array $arguments): void - { - unset($this->objects[$this->computeHash($arguments)]); + public function purge( + array $arguments, + ?ResolveInfo $info = null + ): void { + unset($this->objects[$this->computeHash($arguments, $info)]); } /** @param array $arguments The input arguments passed from GraphQL to the field. */ - public function storeResult(mixed $result, array $arguments): void - { - $this->results[$this->computeHash($arguments)] = $result; + public function storeResult( + mixed $result, + array $arguments, + ?ResolveInfo $info = null + ): void { + $this->results[$this->computeHash($arguments, $info)] = $result; } /** @param array $arguments The input arguments passed from GraphQL to the field. */ - public function hasResult(array $arguments): bool - { - return array_key_exists($this->computeHash($arguments), $this->results); + public function hasResult( + array $arguments, + ?ResolveInfo $info = null + ): bool { + return array_key_exists($this->computeHash($arguments, $info), $this->results); } /** @param array $arguments The input arguments passed from GraphQL to the field. */ - public function getResult(array $arguments): mixed - { - return $this->results[$this->computeHash($arguments)]; + public function getResult( + array $arguments, + ?ResolveInfo $info = null + ): mixed { + return $this->results[$this->computeHash($arguments, $info)]; } } diff --git a/src/QueryField.php b/src/QueryField.php index e4be4cb841..2611599167 100644 --- a/src/QueryField.php +++ b/src/QueryField.php @@ -104,10 +104,10 @@ public function __construct(string $name, OutputType $type, array $arguments, Re $prefetchBuffer = $context->getPrefetchBuffer($this); - $prefetchBuffer->register($source, $args); + $prefetchBuffer->register($source, $args, $info); return new Deferred(function () use ($prefetchBuffer, $source, $args, $context, $info, $prefetchArgs, $prefetchMethodName, $arguments, $resolveFn, $originalResolver) { - if (! $prefetchBuffer->hasResult($args)) { + if (! $prefetchBuffer->hasResult($args, $info)) { if ($originalResolver instanceof SourceResolverInterface) { $originalResolver->setObject($source); } @@ -115,7 +115,7 @@ public function __construct(string $name, OutputType $type, array $arguments, Re // TODO: originalPrefetchResolver and prefetchResolver needed!!! $prefetchCallable = [$originalResolver->getObject(), $prefetchMethodName]; - $sources = $prefetchBuffer->getObjectsByArguments($args); + $sources = $prefetchBuffer->getObjectsByArguments($args, $info); assert(is_callable($prefetchCallable)); $toPassPrefetchArgs = $this->paramsToArguments($prefetchArgs, $source, $args, $context, $info, $prefetchCallable); @@ -123,9 +123,9 @@ public function __construct(string $name, OutputType $type, array $arguments, Re array_unshift($toPassPrefetchArgs, $sources); assert(is_callable($prefetchCallable)); $prefetchResult = $prefetchCallable(...$toPassPrefetchArgs); - $prefetchBuffer->storeResult($prefetchResult, $args); + $prefetchBuffer->storeResult($prefetchResult, $args, $info); } else { - $prefetchResult = $prefetchBuffer->getResult($args); + $prefetchResult = $prefetchBuffer->getResult($args, $info); } foreach ($arguments as $argument) { diff --git a/tests/Fixtures/Integration/Controllers/CompanyController.php b/tests/Fixtures/Integration/Controllers/CompanyController.php new file mode 100644 index 0000000000..889ffdf72d --- /dev/null +++ b/tests/Fixtures/Integration/Controllers/CompanyController.php @@ -0,0 +1,17 @@ + new Contact('Joe'), + 'Bill' => new Contact('Bill'), + default => null, + }; + } + /** * @Mutation() * @param Contact $contact diff --git a/tests/Fixtures/Integration/Models/Company.php b/tests/Fixtures/Integration/Models/Company.php new file mode 100644 index 0000000000..d091cd5a21 --- /dev/null +++ b/tests/Fixtures/Integration/Models/Company.php @@ -0,0 +1,18 @@ +name; + } + + /** + * @Field(prefetchMethod="prefetchContacts") + */ + public function getContact(Company $company, array $contacts): ?Contact + { + return $contacts[$company->name] ?? null; + } + + public function prefetchContacts(array $companies): array + { + $contacts = []; + + foreach ($companies as $company) { + $contacts[$company->name] = new Contact('Kate'); + } + + return $contacts; + } +} diff --git a/tests/Fixtures/Integration/Types/ContactType.php b/tests/Fixtures/Integration/Types/ContactType.php index aa817b3c5d..de7cf1c415 100644 --- a/tests/Fixtures/Integration/Types/ContactType.php +++ b/tests/Fixtures/Integration/Types/ContactType.php @@ -3,6 +3,7 @@ namespace TheCodingMachine\GraphQLite\Fixtures\Integration\Types; +use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Post; use function array_search; use function strtoupper; use TheCodingMachine\GraphQLite\Annotations\ExtendType; @@ -52,4 +53,52 @@ public function prefetchContacts(iterable $contacts, string $prefix) 'prefix' => $prefix ]; } + + /** + * @Field(prefetchMethod="prefetchPosts") + * @return Post[]|null + */ + public function getPosts($contact, $posts): ?array + { + return $posts[$contact->getName()] ?? null; + } + + public function prefetchPosts(iterable $contacts): array + { + $posts = []; + foreach ($contacts as $contact) { + $contactPost = array_filter( + $this->getContactPosts(), + fn(Post $post) => $post->author?->getName() === $contact->getName() + ); + + if ([] === $contactPost) { + continue; + } + + $posts[$contact->getName()] = $contactPost; + } + + return $posts; + } + + private function getContactPosts(): array + { + return [ + $this->generatePost('First Joe post', '1', new Contact('Joe')), + $this->generatePost('First Bill post', '2', new Contact('Bill')), + $this->generatePost('First Kate post', '3', new Contact('Kate')), + ]; + } + + private function generatePost( + string $title, + string $id, + Contact $author, + ): Post { + $post = new Post($title); + $post->id = $id; + $post->author = $author; + return $post; + } } diff --git a/tests/Fixtures/Integration/Types/PostType.php b/tests/Fixtures/Integration/Types/PostType.php new file mode 100644 index 0000000000..d780f6539f --- /dev/null +++ b/tests/Fixtures/Integration/Types/PostType.php @@ -0,0 +1,31 @@ +id; + } + + /** + * @Field() + */ + public function getTitle(Post $post): string + { + return $post->title; + } +} diff --git a/tests/Integration/EndToEndTest.php b/tests/Integration/EndToEndTest.php index a8d5fb9bad..f1409f10f1 100644 --- a/tests/Integration/EndToEndTest.php +++ b/tests/Integration/EndToEndTest.php @@ -8,6 +8,9 @@ use GraphQL\Error\DebugFlag; use GraphQL\Executor\ExecutionResult; use GraphQL\GraphQL; +use GraphQL\Server\Helper; +use GraphQL\Server\OperationParams; +use GraphQL\Server\ServerConfig; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; use stdClass; @@ -21,6 +24,7 @@ use TheCodingMachine\GraphQLite\Containers\EmptyContainer; use TheCodingMachine\GraphQLite\Containers\LazyContainer; use TheCodingMachine\GraphQLite\Context\Context; +use TheCodingMachine\GraphQLite\Exceptions\WebonyxErrorHandler; use TheCodingMachine\GraphQLite\FieldsBuilder; use TheCodingMachine\GraphQLite\Fixtures\Inputs\ValidationException; use TheCodingMachine\GraphQLite\Fixtures\Inputs\Validator; @@ -471,6 +475,70 @@ public function testEndToEnd(): void ], $this->getSuccessResult($result)); } + public function testBatchPrefetching(): void + { + $schema = $this->mainContainer->get(Schema::class); + assert($schema instanceof Schema); + + $schema->assertValid(); + + $queryContact = 'query { contact (name: "Joe") { name posts { id title } } } '; + $queryCompanyWithContact = 'query { company (id: "1"){ name contact { name posts { id title } } } } '; + + $config = ServerConfig::create( + [ + 'schema' => $schema, + 'context' => new Context(), + 'queryBatching' => true, + 'errorFormatter' => [WebonyxErrorHandler::class, 'errorFormatter'], + 'errorsHandler' => [WebonyxErrorHandler::class, 'errorHandler'], + ] + ); + + $result = (new Helper())->executeBatch( + $config, + [ + /** Set specific prefetch result to buffer */ + OperationParams::create(['query' => $queryContact]), + /** Use prefetch data from previous operation instead of getting specific prefetch */ + OperationParams::create(['query' => $queryCompanyWithContact]), + ] + ); + + $this->assertSame( + [ + 'contact' => [ + 'name' => 'Joe', + 'posts' => [ + [ + 'id' => 1, + 'title' => 'First Joe post', + ], + ], + ], + ], + $this->getSuccessResult($result[0]) + ); + + $this->assertSame( + [ + 'company' => [ + 'name' => 'Company', + 'contact' => [ + 'name' => 'Kate', + 'posts' => [ + [ + 'id' => 3, + 'title' => 'First Kate post', + ], + ], + ], + ], + ], + $this->getSuccessResult($result[1]) + ); + } + public function testDeprecatedField(): void { $schema = $this->mainContainer->get(Schema::class); diff --git a/tests/SchemaFactoryTest.php b/tests/SchemaFactoryTest.php index 090f8d91fd..e58ef0573e 100644 --- a/tests/SchemaFactoryTest.php +++ b/tests/SchemaFactoryTest.php @@ -14,12 +14,16 @@ use TheCodingMachine\GraphQLite\Containers\BasicAutoWiringContainer; use TheCodingMachine\GraphQLite\Containers\EmptyContainer; use TheCodingMachine\GraphQLite\Fixtures\Integration\Controllers\ContactController; +use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Company; use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Contact; +use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Post; use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\User; +use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\CompanyType; use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\ContactFactory; use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\ContactOtherType; use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\ContactType; use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\ExtendedContactType; +use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\PostType; use TheCodingMachine\GraphQLite\Mappers\CannotMapTypeException; use TheCodingMachine\GraphQLite\Mappers\CompositeTypeMapper; use TheCodingMachine\GraphQLite\Mappers\DuplicateMappingException; @@ -117,6 +121,10 @@ public function testCreateSchemaOnlyWithFactories(): void ContactFactory::class, ContactOtherType::class, ContactType::class, + Post::class, + PostType::class, + Company::class, + CompanyType::class, ExtendedContactType::class, User::class, ])); From dbeb874294ac329dc86ef9ecbcecf7892ddb2122 Mon Sep 17 00:00:00 2001 From: Olexandr Grynchuk Date: Fri, 8 Mar 2024 10:38:51 +0200 Subject: [PATCH 2/7] Fix phpstan errors --- src/PrefetchBuffer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PrefetchBuffer.php b/src/PrefetchBuffer.php index fe3db2afa2..5d4d2e8f1c 100644 --- a/src/PrefetchBuffer.php +++ b/src/PrefetchBuffer.php @@ -36,7 +36,7 @@ private function computeHash( ): string { if ( null === $info - || null === ($queryBody = $info->operation->loc?->source->body) + || null === ($queryBody = $info->operation->loc?->source?->body) ) { return md5(serialize($arguments)); } From 8c648a54fb668c4801e2171b15e2486467638010 Mon Sep 17 00:00:00 2001 From: grynchuk Date: Fri, 8 Mar 2024 15:04:16 +0200 Subject: [PATCH 3/7] Fix after pull master and resolving conflicts --- src/Parameters/PrefetchDataParameter.php | 10 ++++---- src/PrefetchBuffer.php | 1 + .../Integration/Types/CompanyType.php | 12 ++++++---- .../Integration/Types/ContactType.php | 23 +++++++++++-------- tests/SchemaFactoryTest.php | 1 - 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/Parameters/PrefetchDataParameter.php b/src/Parameters/PrefetchDataParameter.php index fe81e4aceb..4b233c5e3c 100644 --- a/src/Parameters/PrefetchDataParameter.php +++ b/src/Parameters/PrefetchDataParameter.php @@ -43,7 +43,7 @@ public function resolve(object|null $source, array $args, mixed $context, Resolv } $prefetchBuffer = $context->getPrefetchBuffer($this); - $prefetchBuffer->register($source, $args); + $prefetchBuffer->register($source, $args, $info); // The way this works is simple: GraphQL first iterates over every requested field and calls ->resolve() // on it. That, in turn, calls this method. GraphQL doesn't need the actual value just yet; it simply @@ -53,20 +53,20 @@ public function resolve(object|null $source, array $args, mixed $context, Resolv // needed, GraphQL calls the callback of Deferred below. That's when we call the prefetch method, // already knowing all the requested fields (source-arguments combinations). return new Deferred(function () use ($info, $context, $args, $prefetchBuffer) { - if (! $prefetchBuffer->hasResult($args)) { + if (! $prefetchBuffer->hasResult($args, $info)) { $prefetchResult = $this->computePrefetch($args, $context, $info, $prefetchBuffer); - $prefetchBuffer->storeResult($prefetchResult, $args); + $prefetchBuffer->storeResult($prefetchResult, $args, $info); } - return $prefetchResult ?? $prefetchBuffer->getResult($args); + return $prefetchResult ?? $prefetchBuffer->getResult($args, $info); }); } /** @param array $args */ private function computePrefetch(array $args, mixed $context, ResolveInfo $info, PrefetchBuffer $prefetchBuffer): mixed { - $sources = $prefetchBuffer->getObjectsByArguments($args); + $sources = $prefetchBuffer->getObjectsByArguments($args, $info); $toPassPrefetchArgs = QueryField::paramsToArguments($this->fieldName, $this->parameters, null, $args, $context, $info, $this->resolver); return ($this->resolver)($sources, ...$toPassPrefetchArgs); diff --git a/src/PrefetchBuffer.php b/src/PrefetchBuffer.php index 84701d744c..9ca9312f8b 100644 --- a/src/PrefetchBuffer.php +++ b/src/PrefetchBuffer.php @@ -36,6 +36,7 @@ private function computeHash( ): string { if ( null === $info + || false === isset($info->operation) || null === ($queryBody = $info->operation->loc?->source?->body) ) { return md5(serialize($arguments)); diff --git a/tests/Fixtures/Integration/Types/CompanyType.php b/tests/Fixtures/Integration/Types/CompanyType.php index 28836a5968..98fded498e 100644 --- a/tests/Fixtures/Integration/Types/CompanyType.php +++ b/tests/Fixtures/Integration/Types/CompanyType.php @@ -6,6 +6,7 @@ use TheCodingMachine\GraphQLite\Annotations\ExtendType; use TheCodingMachine\GraphQLite\Annotations\Field; +use TheCodingMachine\GraphQLite\Annotations\Prefetch; use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Company; use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Contact; @@ -23,14 +24,17 @@ public function getName(Company $company): string } /** - * @Field(prefetchMethod="prefetchContacts") + * @Field() */ - public function getContact(Company $company, array $contacts): ?Contact - { + public function getContact( + Company $company, + #[Prefetch('prefetchContacts')] + array $contacts + ): ?Contact { return $contacts[$company->name] ?? null; } - public function prefetchContacts(array $companies): array + public static function prefetchContacts(array $companies): array { $contacts = []; diff --git a/tests/Fixtures/Integration/Types/ContactType.php b/tests/Fixtures/Integration/Types/ContactType.php index ee01d0ea65..90e2777c74 100644 --- a/tests/Fixtures/Integration/Types/ContactType.php +++ b/tests/Fixtures/Integration/Types/ContactType.php @@ -56,20 +56,23 @@ public static function prefetchContacts(iterable $contacts, string $prefix) } /** - * @Field(prefetchMethod="prefetchPosts") + * @Field() * @return Post[]|null */ - public function getPosts($contact, $posts): ?array - { + public function getPosts( + Contact $contact, + #[Prefetch('prefetchPosts')] + $posts + ): ?array { return $posts[$contact->getName()] ?? null; } - public function prefetchPosts(iterable $contacts): array + public static function prefetchPosts(iterable $contacts): array { $posts = []; foreach ($contacts as $contact) { $contactPost = array_filter( - $this->getContactPosts(), + self::getContactPosts(), fn(Post $post) => $post->author?->getName() === $contact->getName() ); @@ -83,16 +86,16 @@ public function prefetchPosts(iterable $contacts): array return $posts; } - private function getContactPosts(): array + private static function getContactPosts(): array { return [ - $this->generatePost('First Joe post', '1', new Contact('Joe')), - $this->generatePost('First Bill post', '2', new Contact('Bill')), - $this->generatePost('First Kate post', '3', new Contact('Kate')), + self::generatePost('First Joe post', '1', new Contact('Joe')), + self::generatePost('First Bill post', '2', new Contact('Bill')), + self::generatePost('First Kate post', '3', new Contact('Kate')), ]; } - private function generatePost( + private static function generatePost( string $title, string $id, Contact $author, diff --git a/tests/SchemaFactoryTest.php b/tests/SchemaFactoryTest.php index 1639fa040d..9ac3edceb9 100644 --- a/tests/SchemaFactoryTest.php +++ b/tests/SchemaFactoryTest.php @@ -28,7 +28,6 @@ use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\ContactType; use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\ExtendedContactType; use TheCodingMachine\GraphQLite\Fixtures\Integration\Types\PostType; -use TheCodingMachine\GraphQLite\Mappers\CannotMapTypeException; use TheCodingMachine\GraphQLite\Fixtures\TestSelfType; use TheCodingMachine\GraphQLite\Mappers\CompositeTypeMapper; use TheCodingMachine\GraphQLite\Mappers\DuplicateMappingException; From c5da1f08a74d6b6579de6ab2778d715761c3f8de Mon Sep 17 00:00:00 2001 From: grynchuk Date: Fri, 8 Mar 2024 15:25:02 +0200 Subject: [PATCH 4/7] Fix cs --- src/PrefetchBuffer.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/PrefetchBuffer.php b/src/PrefetchBuffer.php index 9ca9312f8b..80235385f9 100644 --- a/src/PrefetchBuffer.php +++ b/src/PrefetchBuffer.php @@ -5,6 +5,7 @@ namespace TheCodingMachine\GraphQLite; use GraphQL\Type\Definition\ResolveInfo; + use function array_key_exists; use function md5; use function serialize; @@ -24,7 +25,7 @@ class PrefetchBuffer public function register( object $object, array $arguments, - ?ResolveInfo $info = null + mixed $info = null, ): void { $this->objects[$this->computeHash($arguments, $info)][] = $object; } @@ -32,16 +33,17 @@ public function register( /** @param array $arguments The input arguments passed from GraphQL to the field. */ private function computeHash( array $arguments, - ?ResolveInfo $info = null + mixed $info = null, ): string { if ( - null === $info - || false === isset($info->operation) - || null === ($queryBody = $info->operation->loc?->source?->body) + $info instanceof ResolveInfo + && isset($info->operation) + && $info->operation->loc?->source?->body !== null ) { - return md5(serialize($arguments)); + return md5(serialize($arguments) . $info->operation->loc?->source?->body); } - return md5(serialize($arguments) . $queryBody); + + return md5(serialize($arguments)); } /** @@ -51,7 +53,7 @@ private function computeHash( */ public function getObjectsByArguments( array $arguments, - ?ResolveInfo $info = null + mixed $info = null, ): array { return $this->objects[$this->computeHash($arguments, $info)] ?? []; } @@ -59,7 +61,7 @@ public function getObjectsByArguments( /** @param array $arguments The input arguments passed from GraphQL to the field. */ public function purge( array $arguments, - ?ResolveInfo $info = null + mixed $info = null, ): void { unset($this->objects[$this->computeHash($arguments, $info)]); } @@ -68,7 +70,7 @@ public function purge( public function storeResult( mixed $result, array $arguments, - ?ResolveInfo $info = null + mixed $info = null, ): void { $this->results[$this->computeHash($arguments, $info)] = $result; } @@ -76,7 +78,7 @@ public function storeResult( /** @param array $arguments The input arguments passed from GraphQL to the field. */ public function hasResult( array $arguments, - ?ResolveInfo $info = null + mixed $info = null, ): bool { return array_key_exists($this->computeHash($arguments, $info), $this->results); } @@ -84,7 +86,7 @@ public function hasResult( /** @param array $arguments The input arguments passed from GraphQL to the field. */ public function getResult( array $arguments, - ?ResolveInfo $info = null + mixed $info = null, ): mixed { return $this->results[$this->computeHash($arguments, $info)]; } From aa802852349bd89245f31dd6c3183e5ba66cfeca Mon Sep 17 00:00:00 2001 From: grynchuk Date: Fri, 8 Mar 2024 15:28:49 +0200 Subject: [PATCH 5/7] Fix phpstan --- src/PrefetchBuffer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PrefetchBuffer.php b/src/PrefetchBuffer.php index 80235385f9..f2ed43d27d 100644 --- a/src/PrefetchBuffer.php +++ b/src/PrefetchBuffer.php @@ -40,7 +40,7 @@ private function computeHash( && isset($info->operation) && $info->operation->loc?->source?->body !== null ) { - return md5(serialize($arguments) . $info->operation->loc?->source?->body); + return md5(serialize($arguments) . $info->operation->loc->source->body); } return md5(serialize($arguments)); From 5b6b25fbfa781d18a803b063afc7e6164aa7b871 Mon Sep 17 00:00:00 2001 From: grynchuk Date: Fri, 8 Mar 2024 17:38:34 +0200 Subject: [PATCH 6/7] Bring back ResolveInfo|null instead of ?ResolveInfo --- src/PrefetchBuffer.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/PrefetchBuffer.php b/src/PrefetchBuffer.php index f2ed43d27d..8b1afb02a0 100644 --- a/src/PrefetchBuffer.php +++ b/src/PrefetchBuffer.php @@ -25,7 +25,7 @@ class PrefetchBuffer public function register( object $object, array $arguments, - mixed $info = null, + ResolveInfo|null $info = null, ): void { $this->objects[$this->computeHash($arguments, $info)][] = $object; } @@ -33,7 +33,7 @@ public function register( /** @param array $arguments The input arguments passed from GraphQL to the field. */ private function computeHash( array $arguments, - mixed $info = null, + ResolveInfo|null $info, ): string { if ( $info instanceof ResolveInfo @@ -53,7 +53,7 @@ private function computeHash( */ public function getObjectsByArguments( array $arguments, - mixed $info = null, + ResolveInfo|null $info = null, ): array { return $this->objects[$this->computeHash($arguments, $info)] ?? []; } @@ -61,7 +61,7 @@ public function getObjectsByArguments( /** @param array $arguments The input arguments passed from GraphQL to the field. */ public function purge( array $arguments, - mixed $info = null, + ResolveInfo|null $info = null, ): void { unset($this->objects[$this->computeHash($arguments, $info)]); } @@ -70,7 +70,7 @@ public function purge( public function storeResult( mixed $result, array $arguments, - mixed $info = null, + ResolveInfo|null $info = null, ): void { $this->results[$this->computeHash($arguments, $info)] = $result; } @@ -78,7 +78,7 @@ public function storeResult( /** @param array $arguments The input arguments passed from GraphQL to the field. */ public function hasResult( array $arguments, - mixed $info = null, + ResolveInfo|null $info = null, ): bool { return array_key_exists($this->computeHash($arguments, $info), $this->results); } @@ -86,7 +86,7 @@ public function hasResult( /** @param array $arguments The input arguments passed from GraphQL to the field. */ public function getResult( array $arguments, - mixed $info = null, + ResolveInfo|null $info = null, ): mixed { return $this->results[$this->computeHash($arguments, $info)]; } From 5364cde5dadb23a7b7ddf57300232a5840ac8a69 Mon Sep 17 00:00:00 2001 From: grynchuk Date: Mon, 11 Mar 2024 10:06:45 +0200 Subject: [PATCH 7/7] fix cs --- .../Integration/Controllers/CompanyController.php | 2 +- tests/Fixtures/Integration/Models/Company.php | 4 +--- tests/Fixtures/Integration/Types/CompanyType.php | 13 ++++--------- tests/Fixtures/Integration/Types/ContactType.php | 5 +++-- tests/Fixtures/Integration/Types/PostType.php | 12 +++--------- 5 files changed, 12 insertions(+), 24 deletions(-) diff --git a/tests/Fixtures/Integration/Controllers/CompanyController.php b/tests/Fixtures/Integration/Controllers/CompanyController.php index 889ffdf72d..ccb65bc384 100644 --- a/tests/Fixtures/Integration/Controllers/CompanyController.php +++ b/tests/Fixtures/Integration/Controllers/CompanyController.php @@ -9,7 +9,7 @@ class CompanyController { - /** @Query() */ + #[Query] public function getCompany(string $id): Company { return new Company('Company'); diff --git a/tests/Fixtures/Integration/Models/Company.php b/tests/Fixtures/Integration/Models/Company.php index d091cd5a21..75c1e7467f 100644 --- a/tests/Fixtures/Integration/Models/Company.php +++ b/tests/Fixtures/Integration/Models/Company.php @@ -6,9 +6,7 @@ use TheCodingMachine\GraphQLite\Annotations\Type; -/** - * @Type() - */ +#[Type] class Company { public function __construct( diff --git a/tests/Fixtures/Integration/Types/CompanyType.php b/tests/Fixtures/Integration/Types/CompanyType.php index 98fded498e..31a042479f 100644 --- a/tests/Fixtures/Integration/Types/CompanyType.php +++ b/tests/Fixtures/Integration/Types/CompanyType.php @@ -10,22 +10,17 @@ use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Company; use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Contact; -/** - * @ExtendType(class=Company::class) - */ +#[ExtendType(class:Company::class)] class CompanyType { - /** - * @Field() - */ + + #[Field] public function getName(Company $company): string { return $company->name; } - /** - * @Field() - */ + #[Field] public function getContact( Company $company, #[Prefetch('prefetchContacts')] diff --git a/tests/Fixtures/Integration/Types/ContactType.php b/tests/Fixtures/Integration/Types/ContactType.php index 90e2777c74..33ff5449f9 100644 --- a/tests/Fixtures/Integration/Types/ContactType.php +++ b/tests/Fixtures/Integration/Types/ContactType.php @@ -56,9 +56,10 @@ public static function prefetchContacts(iterable $contacts, string $prefix) } /** - * @Field() + * * @return Post[]|null */ + #[Field] public function getPosts( Contact $contact, #[Prefetch('prefetchPosts')] @@ -76,7 +77,7 @@ public static function prefetchPosts(iterable $contacts): array fn(Post $post) => $post->author?->getName() === $contact->getName() ); - if ([] === $contactPost) { + if (!$contactPost) { continue; } diff --git a/tests/Fixtures/Integration/Types/PostType.php b/tests/Fixtures/Integration/Types/PostType.php index d780f6539f..565c783ecb 100644 --- a/tests/Fixtures/Integration/Types/PostType.php +++ b/tests/Fixtures/Integration/Types/PostType.php @@ -8,22 +8,16 @@ use TheCodingMachine\GraphQLite\Annotations\Field; use TheCodingMachine\GraphQLite\Fixtures\Integration\Models\Post; -/** - * @ExtendType(class=Post::class) - */ +#[ExtendType(class:Post::class)] class PostType { - /** - * @Field() - */ + #[Field] public function getId(Post $post): int { return (int) $post->id; } - /** - * @Field() - */ + #[Field] public function getTitle(Post $post): string { return $post->title;