Passed
Push — master ( 3d645a...097498 )
by Tomáš
05:27
created

RequestProcessor::process()   B

Complexity

Conditions 6
Paths 23

Size

Total Lines 41
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 35.6629

Importance

Changes 0
Metric Value
cc 6
eloc 22
nc 23
nop 6
dl 0
loc 41
ccs 1
cts 16
cp 0.0625
crap 35.6629
rs 8.9457
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Portiny\GraphQL\GraphQL;
6
7
use GraphQL\Error\Debug;
8
use GraphQL\Executor\Promise\Promise;
9
use GraphQL\Executor\Promise\PromiseAdapter;
10
use GraphQL\GraphQL;
11
use GraphQL\Type\Definition\ObjectType;
12
use GraphQL\Type\Schema;
13
use Portiny\GraphQL\Contract\Http\Request\RequestParserInterface;
14
use Portiny\GraphQL\Contract\Provider\MutationFieldsProviderInterface;
15
use Portiny\GraphQL\Contract\Provider\QueryFieldsProviderInterface;
16
use Portiny\GraphQL\GraphQL\Schema\SchemaCacheProvider;
17
use Throwable;
18
use Tracy\Debugger;
19
use Tracy\ILogger;
20
21
final class RequestProcessor
22
{
23
	/**
24
	 * @var bool
25
	 */
26
	private $schemaCache = false;
27
28
	/**
29
	 * @var MutationFieldsProviderInterface
30
	 */
31
	private $mutationFieldsProvider;
32 2
33
	/**
34
	 * @var QueryFieldsProviderInterface
35
	 */
36 2
	private $queryFieldsProvider;
37 2
38 2
	/**
39
	 * @var SchemaCacheProvider
40
	 */
41
	private $schemaCacheProvider;
42
43
	public function __construct(
44
		MutationFieldsProviderInterface $mutationFieldsProvider,
45 1
		QueryFieldsProviderInterface $queryFieldsProvider,
46
		SchemaCacheProvider $schemaCacheProvider
47
	) {
48
		$this->mutationFieldsProvider = $mutationFieldsProvider;
49
		$this->queryFieldsProvider = $queryFieldsProvider;
50
		$this->schemaCacheProvider = $schemaCacheProvider;
51
	}
52
53
	public function setSchemaCache(bool $useSchemaCache): void
54 1
	{
55 1
		$this->schemaCache = $useSchemaCache;
56 1
	}
57 1
58 1
	/**
59 1
	 * @param mixed|null $context
60
	 * @param array|null $allowedQueries
61
	 * @param array|null $allowedMutations
62 1
	 */
63
	public function process(
64
		RequestParserInterface $requestParser,
65
		array $rootValue = [],
66
		$context = null,
67
		?array $allowedQueries = null,
68
		?array $allowedMutations = null,
69
		?ILogger $logger = null
70
	): array {
71
		try {
72
			if ($this->schemaCache && $this->schemaCacheProvider->isCached()) {
73
				$schema = $this->schemaCacheProvider->getSchema();
74
			} else {
75
				$schema = $this->createSchema($allowedQueries, $allowedMutations);
76 1
				if ($this->schemaCache) {
77
					$this->schemaCacheProvider->save($schema);
78
				}
79
			}
80
81
			$result = GraphQL::executeQuery(
82
				$schema,
83
				$requestParser->getQuery(),
84
				$rootValue,
85
				$context,
86
				$requestParser->getVariables()
87
			);
88
89
			$output = $result->toArray($this->isDebug());
90
		} catch (Throwable $throwable) {
91
			if ($logger) {
92
				$logger->log($throwable);
93
			}
94
95
			$output = [
96
				'error' => [
97
					'message' => $throwable->getMessage(),
98
					'code' => $throwable->getCode(),
99
				],
100
			];
101
		}
102
103
		return $output;
104
	}
105
106
	/**
107
	 * @param mixed|null $context
108
	 * @param array|null $allowedQueries
109
	 * @param array|null $allowedMutations
110
	 */
111 1
	public function processViaPromise(
112
		PromiseAdapter $promiseAdapter,
113
		RequestParserInterface $requestParser,
114 1
		array $rootValue = [],
115
		$context = null,
116
		?array $allowedQueries = null,
117 1
		?array $allowedMutations = null,
118 1
		?ILogger $logger = null
119 1
	): Promise {
120
		try {
121
			return GraphQL::promiseToExecute(
122 1
				$promiseAdapter,
123
				$this->createSchema($allowedQueries, $allowedMutations),
124
				$requestParser->getQuery(),
125 1
				$rootValue,
126
				$context,
127 1
				$requestParser->getVariables()
128
			);
129
		} catch (Throwable $throwable) {
130 1
			if ($logger) {
131
				$logger->log($throwable);
132 1
			}
133 1
134 1
			return $promiseAdapter->createRejected($throwable);
135
		}
136
	}
137
138 1
	private function createSchema(?array $allowedQueries = null, ?array $allowedMutations = null): Schema
139
	{
140 1
		$configuration = [
141 1
			'query' => $this->createQueryObject($allowedQueries),
142 1
		];
143
144
		$mutationObject = $this->createMutationObject($allowedMutations);
145
		if ($mutationObject->getFields()) {
146
			$configuration['mutation'] = $mutationObject;
147
		}
148
149
		return new Schema($configuration);
150
	}
151
152
	private function isDebug(): int
153
	{
154
		return ! Debugger::$productionMode ? Debug::INCLUDE_DEBUG_MESSAGE | Debug::INCLUDE_TRACE : 0;
155
	}
156
157
	private function createQueryObject(?array $allowedQueries = null): ObjectType
158
	{
159
		return new ObjectType([
160
			'name' => 'Query',
161
			'fields' => $this->queryFieldsProvider->convertFieldsToArray($allowedQueries),
162
		]);
163
	}
164
165
	private function createMutationObject(?array $allowedMutations = null): ObjectType
166
	{
167
		return new ObjectType([
168
			'name' => 'Mutation',
169
			'fields' => $this->mutationFieldsProvider->convertFieldsToArray($allowedMutations),
170
		]);
171
	}
172
}
173