1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Drupal\graphql\GraphQL\Execution; |
4
|
|
|
|
5
|
|
|
use Youshido\GraphQL\Execution\DeferredResolverInterface; |
6
|
|
|
use Youshido\GraphQL\Execution\DeferredResult; |
7
|
|
|
use Youshido\GraphQL\Execution\Processor as BaseProcessor; |
8
|
|
|
use Youshido\GraphQL\Field\FieldInterface; |
9
|
|
|
use Youshido\GraphQL\Type\Enum\AbstractEnumType; |
10
|
|
|
use Youshido\GraphQL\Type\Scalar\AbstractScalarType; |
11
|
|
|
|
12
|
|
|
class Processor extends BaseProcessor { |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* {@inheritdoc} |
16
|
|
|
*/ |
17
|
|
|
public function processPayload($payload, $variables = [], $visitors = []) { |
18
|
|
|
$this->data = []; |
19
|
|
|
|
20
|
|
|
try { |
21
|
|
|
$this->parseAndCreateRequest($payload, $variables); |
22
|
|
|
|
23
|
|
|
if (!empty($reducers)) { |
|
|
|
|
24
|
|
|
$schema = $this->executionContext->getSchema(); |
25
|
|
|
$request = $this->executionContext->getRequest(); |
26
|
|
|
$reducer = new QueryReducer($schema, $request); |
27
|
|
|
|
28
|
|
|
foreach ($visitors as $visitor) { |
29
|
|
|
$reducer->reduceQuery($visitor); |
30
|
|
|
} |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
$operations = $this->executionContext->getRequest()->getAllOperations(); |
34
|
|
|
foreach ($operations as $query) { |
35
|
|
|
if ($operationResult = $this->resolveQuery($query)) { |
36
|
|
|
$this->data = array_replace_recursive($this->data, $operationResult); |
37
|
|
|
}; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
// If the processor found any deferred results, resolve them now. |
41
|
|
|
if (!empty($this->data) && (!empty($this->deferredResultsLeaf) || !empty($this->deferredResultsComplex))) { |
42
|
|
|
try { |
43
|
|
|
while ($deferredResolver = array_shift($this->deferredResultsComplex)) { |
44
|
|
|
$deferredResolver->resolve(); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
// Deferred scalar and enum fields should be resolved last to |
48
|
|
|
// pick up as many as possible for a single batch. |
49
|
|
|
while ($deferredResolver = array_shift($this->deferredResultsLeaf)) { |
50
|
|
|
$deferredResolver->resolve(); |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
catch (\Exception $exception) { |
54
|
|
|
$this->executionContext->addError($exception); |
55
|
|
|
} |
56
|
|
|
finally { |
57
|
|
|
$this->data = static::unpackDeferredResults($this->data); |
58
|
|
|
} |
59
|
|
|
} |
60
|
|
|
} |
61
|
|
|
catch (\Exception $exception) { |
62
|
|
|
$this->executionContext->addError($exception); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
return $this; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* {@inheritdoc} |
70
|
|
|
*/ |
71
|
|
|
protected function deferredResolve($resolvedValue, FieldInterface $field, callable $callback) { |
72
|
|
|
if ($resolvedValue instanceof DeferredResolverInterface) { |
73
|
|
|
$deferredResult = new DeferredResult($resolvedValue, function ($resolvedValue) use ($field, $callback) { |
74
|
|
|
// Allow nested deferred resolvers. |
75
|
|
|
return $this->deferredResolve($resolvedValue, $field, $callback); |
76
|
|
|
}); |
77
|
|
|
|
78
|
|
|
// Whenever we stumble upon a deferred resolver, add it to the queue to be |
79
|
|
|
// resolved later. |
80
|
|
|
$type = $field->getType()->getNamedType(); |
81
|
|
|
if ($type instanceof AbstractScalarType || $type instanceof AbstractEnumType) { |
82
|
|
|
array_push($this->deferredResultsLeaf, $deferredResult); |
83
|
|
|
} |
84
|
|
|
else { |
85
|
|
|
array_push($this->deferredResultsComplex, $deferredResult); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return $deferredResult; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
// For simple values, invoke the callback immediately. |
92
|
|
|
return $callback($resolvedValue); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
} |
This check looks for calls to
isset(...)
orempty()
on variables that are yet undefined. These calls will always produce the same result and can be removed.This is most likely caused by the renaming of a variable or the removal of a function/method parameter.