GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Values::getVariableValues()   C
last analyzed

Complexity

Conditions 15
Paths 32

Size

Total Lines 83
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 15

Importance

Changes 0
Metric Value
eloc 51
dl 0
loc 83
ccs 49
cts 49
cp 1
rs 5.9166
c 0
b 0
f 0
cc 15
nc 32
nop 3
crap 15

How to fix   Long Method    Complexity   

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:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Executor;
6
7
use GraphQL\Error\Error;
8
use GraphQL\Language\AST\ArgumentNode;
9
use GraphQL\Language\AST\BooleanValueNode;
10
use GraphQL\Language\AST\DirectiveNode;
11
use GraphQL\Language\AST\EnumValueDefinitionNode;
12
use GraphQL\Language\AST\EnumValueNode;
13
use GraphQL\Language\AST\FieldDefinitionNode;
14
use GraphQL\Language\AST\FieldNode;
15
use GraphQL\Language\AST\FloatValueNode;
16
use GraphQL\Language\AST\FragmentSpreadNode;
17
use GraphQL\Language\AST\InlineFragmentNode;
18
use GraphQL\Language\AST\IntValueNode;
19
use GraphQL\Language\AST\ListValueNode;
20
use GraphQL\Language\AST\Node;
21
use GraphQL\Language\AST\NodeList;
22
use GraphQL\Language\AST\NullValueNode;
23
use GraphQL\Language\AST\ObjectValueNode;
24
use GraphQL\Language\AST\StringValueNode;
25
use GraphQL\Language\AST\ValueNode;
26
use GraphQL\Language\AST\VariableDefinitionNode;
27
use GraphQL\Language\AST\VariableNode;
28
use GraphQL\Language\Printer;
29
use GraphQL\Type\Definition\Directive;
30
use GraphQL\Type\Definition\EnumType;
31
use GraphQL\Type\Definition\FieldDefinition;
32
use GraphQL\Type\Definition\InputObjectType;
33
use GraphQL\Type\Definition\InputType;
34
use GraphQL\Type\Definition\ListOfType;
35
use GraphQL\Type\Definition\NonNull;
36
use GraphQL\Type\Definition\ScalarType;
37
use GraphQL\Type\Definition\Type;
38
use GraphQL\Type\Schema;
39
use GraphQL\Utils\AST;
40
use GraphQL\Utils\TypeInfo;
41
use GraphQL\Utils\Utils;
42
use GraphQL\Utils\Value;
43
use stdClass;
44
use Throwable;
45
use function array_key_exists;
46
use function array_map;
47
use function sprintf;
48
49
class Values
50
{
51
    /**
52
     * Prepares an object map of variables of the correct type based on the provided
53
     * variable definitions and arbitrary input. If the input cannot be coerced
54
     * to match the variable definitions, a Error will be thrown.
55
     *
56
     * @param VariableDefinitionNode[] $varDefNodes
57
     * @param mixed[]                  $inputs
58
     *
59
     * @return mixed[]
60
     */
61 260
    public static function getVariableValues(Schema $schema, $varDefNodes, array $inputs)
62
    {
63 260
        $errors        = [];
64 260
        $coercedValues = [];
65 260
        foreach ($varDefNodes as $varDefNode) {
66 62
            $varName = $varDefNode->variable->name->value;
67
            /** @var InputType|Type $varType */
68 62
            $varType = TypeInfo::typeFromAST($schema, $varDefNode->type);
69
70 62
            if (! Type::isInputType($varType)) {
71
                // Must use input types for variables. This should be caught during
72
                // validation, however is checked again here for safety.
73 2
                $errors[] = new Error(
74 2
                    sprintf(
75 2
                        'Variable "$%s" expected value of type "%s" which cannot be used as an input type.',
76 2
                        $varName,
77 2
                        Printer::doPrint($varDefNode->type)
78
                    ),
79 2
                    [$varDefNode->type]
80
                );
81
            } else {
82 60
                $hasValue = array_key_exists($varName, $inputs);
83 60
                $value    = $hasValue ? $inputs[$varName] : Utils::undefined();
84
85 60
                if (! $hasValue && $varDefNode->defaultValue) {
86
                    // If no value was provided to a variable with a default value,
87
                    // use the default value.
88 3
                    $coercedValues[$varName] = AST::valueFromAST($varDefNode->defaultValue, $varType);
89 58
                } elseif ((! $hasValue || $value === null) && ($varType instanceof NonNull)) {
90
                    // If no value or a nullish value was provided to a variable with a
91
                    // non-null type (required), produce an error.
92 4
                    $errors[] = new Error(
93 4
                        sprintf(
94 4
                            $hasValue
95 3
                                ? 'Variable "$%s" of non-null type "%s" must not be null.'
96 4
                                : 'Variable "$%s" of required type "%s" was not provided.',
97 4
                            $varName,
98 4
                            Utils::printSafe($varType)
99
                        ),
100 4
                        [$varDefNode]
101
                    );
102 54
                } elseif ($hasValue) {
103 49
                    if ($value === null) {
104
                        // If the explicit value `null` was provided, an entry in the coerced
105
                        // values must exist as the value `null`.
106 4
                        $coercedValues[$varName] = null;
107
                    } else {
108
                        // Otherwise, a non-null value was provided, coerce it to the expected
109
                        // type or report an error if coercion fails.
110 46
                        $coerced = Value::coerceValue($value, $varType, $varDefNode);
0 ignored issues
show
Bug introduced by
$varType of type GraphQL\Type\Definition\Type is incompatible with the type GraphQL\Type\Definition\InputType expected by parameter $type of GraphQL\Utils\Value::coerceValue(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

110
                        $coerced = Value::coerceValue($value, /** @scrutinizer ignore-type */ $varType, $varDefNode);
Loading history...
111
                        /** @var Error[] $coercionErrors */
112 46
                        $coercionErrors = $coerced['errors'];
113 46
                        if ($coercionErrors) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $coercionErrors of type GraphQL\Error\Error[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
114 14
                            $messagePrelude = sprintf(
115 14
                                'Variable "$%s" got invalid value %s; ',
116 14
                                $varName,
117 14
                                Utils::printSafeJson($value)
118
                            );
119
120 14
                            foreach ($coercionErrors as $error) {
121 14
                                $errors[] = new Error(
122 14
                                    $messagePrelude . $error->getMessage(),
123 14
                                    $error->getNodes(),
124 14
                                    $error->getSource(),
125 14
                                    $error->getPositions(),
126 14
                                    $error->getPath(),
127 14
                                    $error,
128 14
                                    $error->getExtensions()
129
                                );
130
                            }
131
                        } else {
132 62
                            $coercedValues[$varName] = $coerced['value'];
133
                        }
134
                    }
135
                }
136
            }
137
        }
138
139 260
        if (! empty($errors)) {
140 20
            return [$errors, null];
141
        }
142
143 241
        return [null, $coercedValues];
144
    }
145
146
    /**
147
     * Prepares an object map of argument values given a directive definition
148
     * and a AST node which may contain directives. Optionally also accepts a map
149
     * of variable values.
150
     *
151
     * If the directive does not exist on the node, returns undefined.
152
     *
153
     * @param FragmentSpreadNode|FieldNode|InlineFragmentNode|EnumValueDefinitionNode|FieldDefinitionNode $node
154
     * @param mixed[]|null                                                                                $variableValues
155
     *
156
     * @return mixed[]|null
157
     */
158 356
    public static function getDirectiveValues(Directive $directiveDef, $node, $variableValues = null)
159
    {
160 356
        if (isset($node->directives) && $node->directives instanceof NodeList) {
161 356
            $directiveNode = Utils::find(
162 356
                $node->directives,
163
                static function (DirectiveNode $directive) use ($directiveDef) : bool {
164 12
                    return $directive->name->value === $directiveDef->name;
165 356
                }
166
            );
167
168 356
            if ($directiveNode !== null) {
169 9
                return self::getArgumentValues($directiveDef, $directiveNode, $variableValues);
170
            }
171
        }
172
173 353
        return null;
174
    }
175
176
    /**
177
     * Prepares an object map of argument values given a list of argument
178
     * definitions and list of argument AST nodes.
179
     *
180
     * @param FieldDefinition|Directive $def
181
     * @param FieldNode|DirectiveNode   $node
182
     * @param mixed[]                   $variableValues
183
     *
184
     * @return mixed[]
185
     *
186
     * @throws Error
187
     */
188 235
    public static function getArgumentValues($def, $node, $variableValues = null)
189
    {
190 235
        if (empty($def->args)) {
191 175
            return [];
192
        }
193
194 121
        $argumentNodes = $node->arguments;
195 121
        if (empty($argumentNodes)) {
196
            return [];
197
        }
198
199 121
        $argumentValueMap = [];
200 121
        foreach ($argumentNodes as $argumentNode) {
201 103
            $argumentValueMap[$argumentNode->name->value] = $argumentNode->value;
202
        }
203
204 121
        return static::getArgumentValuesForMap($def, $argumentValueMap, $variableValues, $node);
205
    }
206
207
    /**
208
     * @param FieldDefinition|Directive $fieldDefinition
209
     * @param ArgumentNode[]            $argumentValueMap
210
     * @param mixed[]                   $variableValues
211
     * @param Node|null                 $referenceNode
212
     *
213
     * @return mixed[]
214
     *
215
     * @throws Error
216
     */
217 235
    public static function getArgumentValuesForMap($fieldDefinition, $argumentValueMap, $variableValues = null, $referenceNode = null)
218
    {
219 235
        $argumentDefinitions = $fieldDefinition->args;
220 235
        $coercedValues       = [];
221
222 235
        foreach ($argumentDefinitions as $argumentDefinition) {
223 121
            $name              = $argumentDefinition->name;
224 121
            $argType           = $argumentDefinition->getType();
225 121
            $argumentValueNode = $argumentValueMap[$name] ?? null;
226
227 121
            if ($argumentValueNode instanceof VariableNode) {
228 39
                $variableName = $argumentValueNode->name->value;
229 39
                $hasValue     = $variableValues ? array_key_exists($variableName, $variableValues) : false;
230 39
                $isNull       = $hasValue ? $variableValues[$variableName] === null : false;
231
            } else {
232 91
                $hasValue = $argumentValueNode !== null;
233 91
                $isNull   = $argumentValueNode instanceof NullValueNode;
234
            }
235
236 121
            if (! $hasValue && $argumentDefinition->defaultValueExists()) {
237
                // If no argument was provided where the definition has a default value,
238
                // use the default value.
239 15
                $coercedValues[$name] = $argumentDefinition->defaultValue;
240 117
            } elseif ((! $hasValue || $isNull) && ($argType instanceof NonNull)) {
241
                // If no argument or a null value was provided to an argument with a
242
                // non-null type (required), produce a field error.
243 6
                if ($isNull) {
244 2
                    throw new Error(
245 2
                        'Argument "' . $name . '" of non-null type ' .
246 2
                        '"' . Utils::printSafe($argType) . '" must not be null.',
247 2
                        $referenceNode
248
                    );
249
                }
250
251 4
                if ($argumentValueNode instanceof VariableNode) {
252 2
                    $variableName = $argumentValueNode->name->value;
253 2
                    throw new Error(
254 2
                        'Argument "' . $name . '" of required type "' . Utils::printSafe($argType) . '" was ' .
255 2
                        'provided the variable "$' . $variableName . '" which was not provided ' .
256 2
                        'a runtime value.',
257 2
                        [$argumentValueNode]
258
                    );
259
                }
260
261 2
                throw new Error(
262 2
                    'Argument "' . $name . '" of required type ' .
263 2
                    '"' . Utils::printSafe($argType) . '" was not provided.',
264 2
                    $referenceNode
265
                );
266 111
            } elseif ($hasValue) {
267 94
                if ($argumentValueNode instanceof NullValueNode) {
268
                  // If the explicit value `null` was provided, an entry in the coerced
269
                  // values must exist as the value `null`.
270
                    $coercedValues[$name] = null;
271 94
                } elseif ($argumentValueNode instanceof VariableNode) {
272 31
                    $variableName = $argumentValueNode->name->value;
273 31
                    Utils::invariant($variableValues !== null, 'Must exist for hasValue to be true.');
274
                  // Note: This does no further checking that this variable is correct.
275
                  // This assumes that this query has been validated and the variable
276
                  // usage here is of the correct type.
277 31
                    $coercedValues[$name] = $variableValues[$variableName] ?? null;
278
                } else {
279 67
                    $valueNode    = $argumentValueNode;
280 67
                    $coercedValue = AST::valueFromAST($valueNode, $argType, $variableValues);
0 ignored issues
show
Bug introduced by
It seems like $valueNode can also be of type GraphQL\Language\AST\ArgumentNode; however, parameter $valueNode of GraphQL\Utils\AST::valueFromAST() does only seem to accept GraphQL\Language\AST\ValueNode|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

280
                    $coercedValue = AST::valueFromAST(/** @scrutinizer ignore-type */ $valueNode, $argType, $variableValues);
Loading history...
281 67
                    if (Utils::isInvalid($coercedValue)) {
282
                      // Note: ValuesOfCorrectType validation should catch this before
283
                      // execution. This is a runtime check to ensure execution does not
284
                      // continue with an invalid argument value.
285 3
                        throw new Error(
286 3
                            'Argument "' . $name . '" has invalid value ' . Printer::doPrint($valueNode) . '.',
287 3
                            [$argumentValueNode]
288
                        );
289
                    }
290 114
                    $coercedValues[$name] = $coercedValue;
291
                }
292
            }
293
        }
294
295 228
        return $coercedValues;
296
    }
297
298
    /**
299
     * @deprecated as of 8.0 (Moved to \GraphQL\Utils\AST::valueFromAST)
300
     *
301
     * @param VariableNode|NullValueNode|IntValueNode|FloatValueNode|StringValueNode|BooleanValueNode|EnumValueNode|ListValueNode|ObjectValueNode $valueNode
302
     * @param ScalarType|EnumType|InputObjectType|ListOfType|NonNull                                                                              $type
303
     * @param mixed[]|null                                                                                                                        $variables
304
     *
305
     * @return mixed[]|stdClass|null
306
     *
307
     * @codeCoverageIgnore
308
     */
309
    public static function valueFromAST(ValueNode $valueNode, InputType $type, ?array $variables = null)
310
    {
311
        return AST::valueFromAST($valueNode, $type, $variables);
312
    }
313
314
    /**
315
     * @deprecated as of 0.12 (Use coerceValue() directly for richer information)
316
     *
317
     * @param mixed[] $value
318
     *
319
     * @return string[]
320
     *
321
     * @codeCoverageIgnore
322
     * @paarm ScalarType|EnumType|InputObjectType|ListOfType|NonNull $type
323
     */
324
    public static function isValidPHPValue($value, InputType $type)
325
    {
326
        $errors = Value::coerceValue($value, $type)['errors'];
327
328
        return $errors
329
            ? array_map(
330
                static function (Throwable $error) : string {
331
                    return $error->getMessage();
332
                },
333
                $errors
334
            )
335
            : [];
336
    }
337
}
338