Failed Conditions
Pull Request — master (#342)
by Šimon
03:38
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
     * @api
68
     * @param string|DocumentNode $source
69
     * @param mixed               $rootValue
70
     * @param mixed               $context
71
     * @param mixed[]|null        $variableValues
72
     * @param ValidationRule[]    $validationRules
73
     */
74 74
    public static function executeQuery(
75
        SchemaType $schema,
76
        $source,
77
        $rootValue = null,
78
        $context = null,
79
        $variableValues = null,
80
        ?string $operationName = null,
81
        ?callable $fieldResolver = null,
82
        ?array $validationRules = null
83
    ) : ExecutionResult {
84 74
        $promiseAdapter = new SyncPromiseAdapter();
85
86 74
        $promise = self::promiseToExecute(
87 74
            $promiseAdapter,
88 74
            $schema,
89 74
            $source,
90 74
            $rootValue,
91 74
            $context,
92 74
            $variableValues,
93 74
            $operationName,
94 74
            $fieldResolver,
95 74
            $validationRules
96
        );
97
98 74
        return $promiseAdapter->wait($promise);
99
    }
100
101
    /**
102
     * Same as executeQuery(), but requires PromiseAdapter and always returns a Promise.
103
     * Useful for Async PHP platforms.
104
     *
105
     * @api
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 97
    public static function promiseToExecute(
113
        PromiseAdapter $promiseAdapter,
114
        SchemaType $schema,
115
        $source,
116
        $rootValue = null,
117
        $context = null,
118
        $variableValues = null,
119
        ?string $operationName = null,
120
        ?callable $fieldResolver = null,
121
        ?array $validationRules = null
122
    ) : Promise {
123
        try {
124 97
            if ($source instanceof DocumentNode) {
125 21
                $documentNode = $source;
126
            } else {
127 76
                $documentNode = Parser::parse(new Source($source ?: '', 'GraphQL'));
128
            }
129
130
            // FIXME
131 96
            if (empty($validationRules)) {
132
                /** @var QueryComplexity $queryComplexity */
133 95
                $queryComplexity = DocumentValidator::getRule(QueryComplexity::class);
134 95
                $queryComplexity->setRawVariableValues($variableValues);
135
            } else {
136 3
                foreach ($validationRules as $rule) {
137 3
                    if (! ($rule instanceof QueryComplexity)) {
138 3
                        continue;
139
                    }
140
141 2
                    $rule->setRawVariableValues($variableValues);
142
                }
143
            }
144
145 96
            $validationErrors = DocumentValidator::validate($schema, $documentNode, $validationRules);
146
147 96
            if (! empty($validationErrors)) {
148 14
                return $promiseAdapter->createFulfilled(
149 14
                    new ExecutionResult(null, $validationErrors)
150
                );
151
            }
152
153 86
            return Executor::promiseToExecute(
154 86
                $promiseAdapter,
155 86
                $schema,
156 86
                $documentNode,
157 86
                $rootValue,
158 86
                $context,
159 86
                $variableValues,
160 86
                $operationName,
161 86
                $fieldResolver
162
            );
163 1
        } catch (Error $e) {
164 1
            return $promiseAdapter->createFulfilled(
165 1
                new ExecutionResult(null, [$e])
166
            );
167
        }
168
    }
169
170
    /**
171
     * @deprecated Use executeQuery()->toArray() instead
172
     *
173
     * @param string|DocumentNode $source
174
     * @param mixed               $rootValue
175
     * @param mixed               $contextValue
176
     * @param mixed[]|null        $variableValues
177
     * @return Promise|mixed[]
178
     */
179
    public static function execute(
180
        SchemaType $schema,
181
        $source,
182
        $rootValue = null,
183
        $contextValue = null,
184
        $variableValues = null,
185
        ?string $operationName = null
186
    ) {
187
        trigger_error(
188
            __METHOD__ . ' is deprecated, use GraphQL::executeQuery()->toArray() as a quick replacement',
189
            E_USER_DEPRECATED
190
        );
191
192
        $promiseAdapter = Executor::getPromiseAdapter();
193
        $result         = self::promiseToExecute(
194
            $promiseAdapter,
195
            $schema,
196
            $source,
197
            $rootValue,
198
            $contextValue,
199
            $variableValues,
200
            $operationName
201
        );
202
203
        if ($promiseAdapter instanceof SyncPromiseAdapter) {
204
            $result = $promiseAdapter->wait($result)->toArray();
205
        } else {
206
            $result = $result->then(function (ExecutionResult $r) {
207
                return $r->toArray();
208
            });
209
        }
210
211
        return $result;
212
    }
213
214
    /**
215
     * @deprecated renamed to executeQuery()
216
     *
217
     * @param string|DocumentNode $source
218
     * @param mixed               $rootValue
219
     * @param mixed               $contextValue
220
     * @param mixed[]|null        $variableValues
221
     *
222
     * @return ExecutionResult|Promise
223
     */
224
    public static function executeAndReturnResult(
225
        SchemaType $schema,
226
        $source,
227
        $rootValue = null,
228
        $contextValue = null,
229
        $variableValues = null,
230
        ?string $operationName = null
231
    ) {
232
        trigger_error(
233
            __METHOD__ . ' is deprecated, use GraphQL::executeQuery() as a quick replacement',
234
            E_USER_DEPRECATED
235
        );
236
237
        $promiseAdapter = Executor::getPromiseAdapter();
238
        $result         = self::promiseToExecute(
239
            $promiseAdapter,
240
            $schema,
241
            $source,
242
            $rootValue,
243
            $contextValue,
244
            $variableValues,
245
            $operationName
246
        );
247
248
        if ($promiseAdapter instanceof SyncPromiseAdapter) {
249
            $result = $promiseAdapter->wait($result);
250
        }
251
252
        return $result;
253
    }
254
255
    /**
256
     * Returns directives defined in GraphQL spec
257
     *
258
     * @api
259
     * @return Directive[]
260
     */
261 340
    public static function getStandardDirectives() : array
262
    {
263 340
        return array_values(Directive::getInternalDirectives());
264
    }
265
266
    /**
267
     * Returns types defined in GraphQL spec
268
     *
269
     * @api
270
     * @return Type[]
271
     */
272
    public static function getStandardTypes() : array
273
    {
274
        return array_values(Type::getInternalTypes());
275
    }
276
277
    /**
278
     * Returns standard validation rules implementing GraphQL spec
279
     *
280
     * @api
281
     * @return ValidationRule[]
282
     */
283
    public static function getStandardValidationRules() : array
284
    {
285
        return array_values(DocumentValidator::defaultRules());
286
    }
287
288
    public static function setDefaultFieldResolver(callable $fn) : void
289
    {
290
        Executor::setDefaultFieldResolver($fn);
291
    }
292
293
    public static function setPromiseAdapter(?PromiseAdapter $promiseAdapter = null) : void
294
    {
295
        Executor::setPromiseAdapter($promiseAdapter);
296
    }
297
298
    /**
299
     * Returns directives defined in GraphQL spec
300
     *
301
     * @deprecated Renamed to getStandardDirectives
302
     * @return Directive[]
303
     */
304
    public static function getInternalDirectives() : array
305
    {
306
        return self::getStandardDirectives();
307
    }
308
}
309