Completed
Push — master ( ceb02a...91c3aa )
by Tomáš
05:33
created

RequestProcessor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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