Failed Conditions
Push — master ( e1b4d4...c45fa1 )
by Vladimir
05:53
created

GraphQL::promiseToExecute()   B

Complexity

Conditions 8
Paths 37

Size

Total Lines 54
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 8

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 54
ccs 27
cts 27
cp 1
c 0
b 0
f 0
rs 8.2114
cc 8
nc 37
nop 9
crap 8

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL;
6
7
use GraphQL\Error\Error;
8
use GraphQL\Executor\ExecutionResult;
9
use GraphQL\Executor\Executor;
10
use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter;
11
use GraphQL\Executor\Promise\Promise;
12
use GraphQL\Executor\Promise\PromiseAdapter;
13
use GraphQL\Executor\ReferenceExecutor;
14
use GraphQL\Experimental\Executor\CoroutineExecutor;
15
use GraphQL\Language\AST\DocumentNode;
16
use GraphQL\Language\Parser;
17
use GraphQL\Language\Source;
18
use GraphQL\Type\Definition\Directive;
19
use GraphQL\Type\Definition\Type;
20
use GraphQL\Type\Schema as SchemaType;
21
use GraphQL\Validator\DocumentValidator;
22
use GraphQL\Validator\Rules\QueryComplexity;
23
use GraphQL\Validator\Rules\ValidationRule;
24
use function array_values;
25
use function trigger_error;
26
use const E_USER_DEPRECATED;
27
28
/**
29
 * This is the primary facade for fulfilling GraphQL operations.
30
 * See [related documentation](executing-queries.md).
31
 */
32
class GraphQL
33
{
34
    /**
35
     * Executes graphql query.
36
     *
37
     * More sophisticated GraphQL servers, such as those which persist queries,
38
     * may wish to separate the validation and execution phases to a static time
39
     * tooling step, and a server runtime step.
40
     *
41
     * Available options:
42
     *
43
     * schema:
44
     *    The GraphQL type system to use when validating and executing a query.
45
     * source:
46
     *    A GraphQL language formatted string representing the requested operation.
47
     * rootValue:
48
     *    The value provided as the first argument to resolver functions on the top
49
     *    level type (e.g. the query object type).
50
     * context:
51
     *    The value provided as the third argument to all resolvers.
52
     *    Use this to pass current session, user data, etc
53
     * variableValues:
54
     *    A mapping of variable name to runtime value to use for all variables
55
     *    defined in the requestString.
56
     * operationName:
57
     *    The name of the operation to use if requestString contains multiple
58
     *    possible operations. Can be omitted if requestString contains only
59
     *    one operation.
60
     * fieldResolver:
61
     *    A resolver function to use when one is not provided by the schema.
62
     *    If not provided, the default field resolver is used (which looks for a
63
     *    value on the source value with the field's name).
64
     * validationRules:
65
     *    A set of rules for query validation step. Default value is all available rules.
66
     *    Empty array would allow to skip query validation (may be convenient for persisted
67
     *    queries which are validated before persisting and assumed valid during execution)
68
     *
69
     * @param string|DocumentNode $source
70
     * @param mixed               $rootValue
71
     * @param mixed               $context
72
     * @param mixed[]|null        $variableValues
73
     * @param ValidationRule[]    $validationRules
74
     *
75
     * @api
76
     */
77 76
    public static function executeQuery(
78
        SchemaType $schema,
79
        $source,
80
        $rootValue = null,
81
        $context = null,
82
        $variableValues = null,
83
        ?string $operationName = null,
84
        ?callable $fieldResolver = null,
85
        ?array $validationRules = null
86
    ) : ExecutionResult {
87 76
        $promiseAdapter = new SyncPromiseAdapter();
88
89 76
        $promise = self::promiseToExecute(
90 76
            $promiseAdapter,
91 76
            $schema,
92 76
            $source,
93 76
            $rootValue,
94 76
            $context,
95 76
            $variableValues,
96 76
            $operationName,
97 76
            $fieldResolver,
98 76
            $validationRules
99
        );
100
101 76
        return $promiseAdapter->wait($promise);
102
    }
103
104
    /**
105
     * Same as executeQuery(), but requires PromiseAdapter and always returns a Promise.
106
     * Useful for Async PHP platforms.
107
     *
108
     * @param string|DocumentNode   $source
109
     * @param mixed                 $rootValue
110
     * @param mixed                 $context
111
     * @param mixed[]|null          $variableValues
112
     * @param ValidationRule[]|null $validationRules
113
     *
114
     * @api
115
     */
116 100
    public static function promiseToExecute(
117
        PromiseAdapter $promiseAdapter,
118
        SchemaType $schema,
119
        $source,
120
        $rootValue = null,
121
        $context = null,
122
        $variableValues = null,
123
        ?string $operationName = null,
124
        ?callable $fieldResolver = null,
125
        ?array $validationRules = null
126
    ) : Promise {
127
        try {
128 100
            if ($source instanceof DocumentNode) {
129 22
                $documentNode = $source;
130
            } else {
131 78
                $documentNode = Parser::parse(new Source($source ?: '', 'GraphQL'));
132
            }
133
134
            // FIXME
135 99
            if (empty($validationRules)) {
136
                /** @var QueryComplexity $queryComplexity */
137 98
                $queryComplexity = DocumentValidator::getRule(QueryComplexity::class);
138 98
                $queryComplexity->setRawVariableValues($variableValues);
139
            } else {
140 3
                foreach ($validationRules as $rule) {
141 3
                    if (! ($rule instanceof QueryComplexity)) {
142 3
                        continue;
143
                    }
144
145 2
                    $rule->setRawVariableValues($variableValues);
146
                }
147
            }
148
149 99
            $validationErrors = DocumentValidator::validate($schema, $documentNode, $validationRules);
150
151 99
            if (! empty($validationErrors)) {
152 14
                return $promiseAdapter->createFulfilled(
153 14
                    new ExecutionResult(null, $validationErrors)
154
                );
155
            }
156
157 89
            return Executor::promiseToExecute(
158 89
                $promiseAdapter,
159 89
                $schema,
160 89
                $documentNode,
161 89
                $rootValue,
162 89
                $context,
163 89
                $variableValues,
164 89
                $operationName,
165 89
                $fieldResolver
166
            );
167 1
        } catch (Error $e) {
168 1
            return $promiseAdapter->createFulfilled(
169 1
                new ExecutionResult(null, [$e])
170
            );
171
        }
172
    }
173
174
    /**
175
     * @deprecated Use executeQuery()->toArray() instead
176
     *
177
     * @param string|DocumentNode $source
178
     * @param mixed               $rootValue
179
     * @param mixed               $contextValue
180
     * @param mixed[]|null        $variableValues
181
     *
182
     * @return Promise|mixed[]
183
     */
184
    public static function execute(
185
        SchemaType $schema,
186
        $source,
187
        $rootValue = null,
188
        $contextValue = null,
189
        $variableValues = null,
190
        ?string $operationName = null
191
    ) {
192
        trigger_error(
193
            __METHOD__ . ' is deprecated, use GraphQL::executeQuery()->toArray() as a quick replacement',
194
            E_USER_DEPRECATED
195
        );
196
197
        $promiseAdapter = Executor::getPromiseAdapter();
198
        $result         = self::promiseToExecute(
199
            $promiseAdapter,
200
            $schema,
201
            $source,
202
            $rootValue,
203
            $contextValue,
204
            $variableValues,
205
            $operationName
206
        );
207
208
        if ($promiseAdapter instanceof SyncPromiseAdapter) {
209
            $result = $promiseAdapter->wait($result)->toArray();
210
        } else {
211
            $result = $result->then(static function (ExecutionResult $r) {
212
                return $r->toArray();
213
            });
214
        }
215
216
        return $result;
217
    }
218
219
    /**
220
     * @deprecated renamed to executeQuery()
221
     *
222
     * @param string|DocumentNode $source
223
     * @param mixed               $rootValue
224
     * @param mixed               $contextValue
225
     * @param mixed[]|null        $variableValues
226
     *
227
     * @return ExecutionResult|Promise
228
     */
229
    public static function executeAndReturnResult(
230
        SchemaType $schema,
231
        $source,
232
        $rootValue = null,
233
        $contextValue = null,
234
        $variableValues = null,
235
        ?string $operationName = null
236
    ) {
237
        trigger_error(
238
            __METHOD__ . ' is deprecated, use GraphQL::executeQuery() as a quick replacement',
239
            E_USER_DEPRECATED
240
        );
241
242
        $promiseAdapter = Executor::getPromiseAdapter();
243
        $result         = self::promiseToExecute(
244
            $promiseAdapter,
245
            $schema,
246
            $source,
247
            $rootValue,
248
            $contextValue,
249
            $variableValues,
250
            $operationName
251
        );
252
253
        if ($promiseAdapter instanceof SyncPromiseAdapter) {
254
            $result = $promiseAdapter->wait($result);
255
        }
256
257
        return $result;
258
    }
259
260
    /**
261
     * Returns directives defined in GraphQL spec
262
     *
263
     * @return Directive[]
264
     *
265
     * @api
266
     */
267 399
    public static function getStandardDirectives() : array
268
    {
269 399
        return array_values(Directive::getInternalDirectives());
270
    }
271
272
    /**
273
     * Returns types defined in GraphQL spec
274
     *
275
     * @return Type[]
276
     *
277
     * @api
278
     */
279
    public static function getStandardTypes() : array
280
    {
281
        return array_values(Type::getStandardTypes());
282
    }
283
284
    /**
285
     * Replaces standard types with types from this list (matching by name)
286
     * Standard types not listed here remain untouched.
287
     *
288
     * @param Type[] $types
289
     *
290
     * @api
291
     */
292
    public static function overrideStandardTypes(array $types)
293
    {
294
        Type::overrideStandardTypes($types);
295
    }
296
297
    /**
298
     * Returns standard validation rules implementing GraphQL spec
299
     *
300
     * @return ValidationRule[]
301
     *
302
     * @api
303
     */
304
    public static function getStandardValidationRules() : array
305
    {
306
        return array_values(DocumentValidator::defaultRules());
307
    }
308
309
    /**
310
     * Set default resolver implementation
311
     *
312
     * @api
313
     */
314
    public static function setDefaultFieldResolver(callable $fn) : void
315
    {
316
        Executor::setDefaultFieldResolver($fn);
317
    }
318
319
    public static function setPromiseAdapter(?PromiseAdapter $promiseAdapter = null) : void
320
    {
321
        Executor::setPromiseAdapter($promiseAdapter);
322
    }
323
324
    /**
325
     * Experimental: Switch to the new executor
326
     */
327
    public static function useExperimentalExecutor()
328
    {
329
        Executor::setImplementationFactory([CoroutineExecutor::class, 'create']);
330
    }
331
332
    /**
333
     * Experimental: Switch back to the default executor
334
     */
335
    public static function useReferenceExecutor()
336
    {
337
        Executor::setImplementationFactory([ReferenceExecutor::class, 'create']);
338
    }
339
340
    /**
341
     * Returns directives defined in GraphQL spec
342
     *
343
     * @deprecated Renamed to getStandardDirectives
344
     *
345
     * @return Directive[]
346
     */
347
    public static function getInternalDirectives() : array
348
    {
349
        return self::getStandardDirectives();
350
    }
351
}
352