12
12
use TheCodingMachine \GraphQLite \PrefetchBuffer ;
13
13
use TheCodingMachine \GraphQLite \QueryField ;
14
14
15
+ use function array_key_exists ;
15
16
use function assert ;
16
17
17
18
/**
@@ -27,6 +28,7 @@ public function __construct(
27
28
private readonly string $ fieldName ,
28
29
private readonly mixed $ resolver ,
29
30
public readonly array $ parameters ,
31
+ public readonly bool $ returnRequested = false ,
30
32
)
31
33
{
32
34
}
@@ -52,24 +54,40 @@ public function resolve(object|null $source, array $args, mixed $context, Resolv
52
54
// So we record all of these ->resolve() calls, collect them together and when a value is actually
53
55
// needed, GraphQL calls the callback of Deferred below. That's when we call the prefetch method,
54
56
// already knowing all the requested fields (source-arguments combinations).
55
- return new Deferred (function () use ($ info , $ context , $ args , $ prefetchBuffer ) {
56
- if (! $ prefetchBuffer ->hasResult ($ args , $ info )) {
57
- $ prefetchResult = $ this ->computePrefetch ($ args , $ context , $ info , $ prefetchBuffer );
58
-
59
- $ prefetchBuffer ->storeResult ($ prefetchResult , $ args , $ info );
57
+ return new Deferred (function () use ($ source , $ info , $ context , $ args , $ prefetchBuffer ) {
58
+ if (! $ prefetchBuffer ->hasResult ($ source )) {
59
+ $ this ->computePrefetch ($ args , $ context , $ info , $ prefetchBuffer );
60
60
}
61
61
62
- return $ prefetchResult ?? $ prefetchBuffer ->getResult ($ args , $ info );
62
+ return $ prefetchBuffer ->getResult ($ source );
63
63
});
64
64
}
65
65
66
66
/** @param array<string, mixed> $args */
67
- private function computePrefetch (array $ args , mixed $ context , ResolveInfo $ info , PrefetchBuffer $ prefetchBuffer ): mixed
67
+ private function computePrefetch (array $ args , mixed $ context , ResolveInfo $ info , PrefetchBuffer $ prefetchBuffer ): void
68
68
{
69
69
$ sources = $ prefetchBuffer ->getObjectsByArguments ($ args , $ info );
70
+ $ prefetchBuffer ->purge ($ args , $ info );
70
71
$ toPassPrefetchArgs = QueryField::paramsToArguments ($ this ->fieldName , $ this ->parameters , null , $ args , $ context , $ info , $ this ->resolver );
71
72
72
- return ($ this ->resolver )($ sources , ...$ toPassPrefetchArgs );
73
+ $ resolvedValues = ($ this ->resolver )($ sources , ...$ toPassPrefetchArgs );
74
+ if ($ this ->returnRequested ) {
75
+ foreach ($ resolvedValues as $ key => $ resolvedValue ) {
76
+ if (! array_key_exists ($ key , $ sources )) {
77
+ throw new GraphQLRuntimeException (
78
+ 'Called by Prefetch function should accept ' .
79
+ 'Array<key> and return Array<value>, but the function did ' .
80
+ 'not return an Array of the same length as the Array of keys. ' ,
81
+ );
82
+ }
83
+ $ prefetchBuffer ->storeResult ($ sources [$ key ], $ resolvedValue );
84
+ }
85
+ } else {
86
+ foreach ($ sources as $ source ) {
87
+ // map results to each source to support old prefetch behavior
88
+ $ prefetchBuffer ->storeResult ($ source , $ resolvedValues );
89
+ }
90
+ }
73
91
}
74
92
75
93
/** @inheritDoc */
0 commit comments