1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace GraphQL\Server; |
||
6 | |||
7 | use GraphQL\Error\InvariantViolation; |
||
8 | use GraphQL\Executor\Promise\PromiseAdapter; |
||
9 | use GraphQL\Type\Schema; |
||
10 | use GraphQL\Utils\Utils; |
||
11 | use GraphQL\Validator\Rules\ValidationRule; |
||
12 | use function is_array; |
||
13 | use function is_callable; |
||
14 | use function method_exists; |
||
15 | use function sprintf; |
||
16 | use function ucfirst; |
||
17 | |||
18 | /** |
||
19 | * Server configuration class. |
||
20 | * Could be passed directly to server constructor. List of options accepted by **create** method is |
||
21 | * [described in docs](executing-queries.md#server-configuration-options). |
||
22 | * |
||
23 | * Usage example: |
||
24 | * |
||
25 | * $config = GraphQL\Server\ServerConfig::create() |
||
26 | * ->setSchema($mySchema) |
||
27 | * ->setContext($myContext); |
||
28 | * |
||
29 | * $server = new GraphQL\Server\StandardServer($config); |
||
30 | */ |
||
31 | class ServerConfig |
||
32 | { |
||
33 | /** |
||
34 | * Converts an array of options to instance of ServerConfig |
||
35 | * (or just returns empty config when array is not passed). |
||
36 | * |
||
37 | * @param mixed[] $config |
||
38 | * |
||
39 | * @return ServerConfig |
||
40 | * |
||
41 | * @api |
||
42 | */ |
||
43 | 42 | public static function create(array $config = []) |
|
44 | { |
||
45 | 42 | $instance = new static(); |
|
46 | 42 | foreach ($config as $key => $value) { |
|
47 | 2 | $method = 'set' . ucfirst($key); |
|
48 | 2 | if (! method_exists($instance, $method)) { |
|
49 | 1 | throw new InvariantViolation(sprintf('Unknown server config option "%s"', $key)); |
|
50 | } |
||
51 | 1 | $instance->$method($value); |
|
52 | } |
||
53 | |||
54 | 41 | return $instance; |
|
55 | } |
||
56 | |||
57 | /** @var Schema */ |
||
58 | private $schema; |
||
59 | |||
60 | /** @var mixed|callable */ |
||
61 | private $context; |
||
62 | |||
63 | /** @var mixed|callable */ |
||
64 | private $rootValue; |
||
65 | |||
66 | /** @var callable|null */ |
||
67 | private $errorFormatter; |
||
68 | |||
69 | /** @var callable|null */ |
||
70 | private $errorsHandler; |
||
71 | |||
72 | /** @var bool */ |
||
73 | private $debug = false; |
||
74 | |||
75 | /** @var bool */ |
||
76 | private $queryBatching = false; |
||
77 | |||
78 | /** @var ValidationRule[]|callable */ |
||
79 | private $validationRules; |
||
80 | |||
81 | /** @var callable */ |
||
82 | private $fieldResolver; |
||
83 | |||
84 | /** @var PromiseAdapter */ |
||
85 | private $promiseAdapter; |
||
86 | |||
87 | /** @var callable */ |
||
88 | private $persistentQueryLoader; |
||
89 | |||
90 | /** |
||
91 | * @return self |
||
92 | * |
||
93 | * @api |
||
94 | */ |
||
95 | 30 | public function setSchema(Schema $schema) |
|
96 | { |
||
97 | 30 | $this->schema = $schema; |
|
98 | |||
99 | 30 | return $this; |
|
100 | } |
||
101 | |||
102 | /** |
||
103 | * @param mixed|callable $context |
||
104 | * |
||
105 | * @return self |
||
106 | * |
||
107 | * @api |
||
108 | */ |
||
109 | 5 | public function setContext($context) |
|
110 | { |
||
111 | 5 | $this->context = $context; |
|
112 | |||
113 | 5 | return $this; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * @param mixed|callable $rootValue |
||
118 | * |
||
119 | * @return self |
||
120 | * |
||
121 | * @api |
||
122 | */ |
||
123 | 5 | public function setRootValue($rootValue) |
|
124 | { |
||
125 | 5 | $this->rootValue = $rootValue; |
|
126 | |||
127 | 5 | return $this; |
|
128 | } |
||
129 | |||
130 | /** |
||
131 | * Expects function(Throwable $e) : array |
||
132 | * |
||
133 | * @return self |
||
134 | * |
||
135 | * @api |
||
136 | */ |
||
137 | 3 | public function setErrorFormatter(callable $errorFormatter) |
|
138 | { |
||
139 | 3 | $this->errorFormatter = $errorFormatter; |
|
140 | |||
141 | 3 | return $this; |
|
142 | } |
||
143 | |||
144 | /** |
||
145 | * Expects function(array $errors, callable $formatter) : array |
||
146 | * |
||
147 | * @return self |
||
148 | * |
||
149 | * @api |
||
150 | */ |
||
151 | 2 | public function setErrorsHandler(callable $handler) |
|
152 | { |
||
153 | 2 | $this->errorsHandler = $handler; |
|
154 | |||
155 | 2 | return $this; |
|
156 | } |
||
157 | |||
158 | /** |
||
159 | * Set validation rules for this server. |
||
160 | * |
||
161 | * @param ValidationRule[]|callable $validationRules |
||
162 | * |
||
163 | * @return self |
||
164 | * |
||
165 | * @api |
||
166 | */ |
||
167 | 9 | public function setValidationRules($validationRules) |
|
168 | { |
||
169 | 9 | if (! is_callable($validationRules) && ! is_array($validationRules) && $validationRules !== null) { |
|
170 | 1 | throw new InvariantViolation( |
|
171 | 'Server config expects array of validation rules or callable returning such array, but got ' . |
||
172 | 1 | Utils::printSafe($validationRules) |
|
173 | ); |
||
174 | } |
||
175 | |||
176 | 8 | $this->validationRules = $validationRules; |
|
177 | |||
178 | 8 | return $this; |
|
179 | } |
||
180 | |||
181 | /** |
||
182 | * @return self |
||
183 | * |
||
184 | * @api |
||
185 | */ |
||
186 | 2 | public function setFieldResolver(callable $fieldResolver) |
|
187 | { |
||
188 | 2 | $this->fieldResolver = $fieldResolver; |
|
189 | |||
190 | 2 | return $this; |
|
191 | } |
||
192 | |||
193 | /** |
||
194 | * Expects function($queryId, OperationParams $params) : string|DocumentNode |
||
195 | * |
||
196 | * This function must return query string or valid DocumentNode. |
||
197 | * |
||
198 | * @return self |
||
199 | * |
||
200 | * @api |
||
201 | */ |
||
202 | 6 | public function setPersistentQueryLoader(callable $persistentQueryLoader) |
|
203 | { |
||
204 | 6 | $this->persistentQueryLoader = $persistentQueryLoader; |
|
205 | |||
206 | 6 | return $this; |
|
207 | } |
||
208 | |||
209 | /** |
||
210 | * Set response debug flags. See GraphQL\Error\Debug class for a list of all available flags |
||
211 | * |
||
212 | * @param bool|int $set |
||
213 | * |
||
214 | * @return self |
||
215 | * |
||
216 | * @api |
||
217 | */ |
||
218 | 4 | public function setDebug($set = true) |
|
219 | { |
||
220 | 4 | $this->debug = $set; |
|
0 ignored issues
–
show
|
|||
221 | |||
222 | 4 | return $this; |
|
223 | } |
||
224 | |||
225 | /** |
||
226 | * Allow batching queries (disabled by default) |
||
227 | * |
||
228 | * @api |
||
229 | */ |
||
230 | 3 | public function setQueryBatching(bool $enableBatching) : self |
|
231 | { |
||
232 | 3 | $this->queryBatching = $enableBatching; |
|
233 | |||
234 | 3 | return $this; |
|
235 | } |
||
236 | |||
237 | /** |
||
238 | * @return self |
||
239 | * |
||
240 | * @api |
||
241 | */ |
||
242 | 2 | public function setPromiseAdapter(PromiseAdapter $promiseAdapter) |
|
243 | { |
||
244 | 2 | $this->promiseAdapter = $promiseAdapter; |
|
245 | |||
246 | 2 | return $this; |
|
247 | } |
||
248 | |||
249 | /** |
||
250 | * @return mixed|callable |
||
251 | */ |
||
252 | 25 | public function getContext() |
|
253 | { |
||
254 | 25 | return $this->context; |
|
255 | } |
||
256 | |||
257 | /** |
||
258 | * @return mixed|callable |
||
259 | */ |
||
260 | 25 | public function getRootValue() |
|
261 | { |
||
262 | 25 | return $this->rootValue; |
|
263 | } |
||
264 | |||
265 | /** |
||
266 | * @return Schema |
||
267 | */ |
||
268 | 31 | public function getSchema() |
|
269 | { |
||
270 | 31 | return $this->schema; |
|
271 | } |
||
272 | |||
273 | /** |
||
274 | * @return callable|null |
||
275 | */ |
||
276 | 28 | public function getErrorFormatter() |
|
277 | { |
||
278 | 28 | return $this->errorFormatter; |
|
279 | } |
||
280 | |||
281 | /** |
||
282 | * @return callable|null |
||
283 | */ |
||
284 | 27 | public function getErrorsHandler() |
|
285 | { |
||
286 | 27 | return $this->errorsHandler; |
|
287 | } |
||
288 | |||
289 | /** |
||
290 | * @return PromiseAdapter |
||
291 | */ |
||
292 | 31 | public function getPromiseAdapter() |
|
293 | { |
||
294 | 31 | return $this->promiseAdapter; |
|
295 | } |
||
296 | |||
297 | /** |
||
298 | * @return ValidationRule[]|callable |
||
299 | */ |
||
300 | 25 | public function getValidationRules() |
|
301 | { |
||
302 | 25 | return $this->validationRules; |
|
303 | } |
||
304 | |||
305 | /** |
||
306 | * @return callable |
||
307 | */ |
||
308 | 25 | public function getFieldResolver() |
|
309 | { |
||
310 | 25 | return $this->fieldResolver; |
|
311 | } |
||
312 | |||
313 | /** |
||
314 | * @return callable |
||
315 | */ |
||
316 | 8 | public function getPersistentQueryLoader() |
|
317 | { |
||
318 | 8 | return $this->persistentQueryLoader; |
|
319 | } |
||
320 | |||
321 | /** |
||
322 | * @return bool |
||
323 | */ |
||
324 | 28 | public function getDebug() |
|
325 | { |
||
326 | 28 | return $this->debug; |
|
327 | } |
||
328 | |||
329 | /** |
||
330 | * @return bool |
||
331 | */ |
||
332 | 5 | public function getQueryBatching() |
|
333 | { |
||
334 | 5 | return $this->queryBatching; |
|
335 | } |
||
336 | } |
||
337 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.