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