Passed
Pull Request — master (#19)
by Christoffer
02:11
created

getArgumentValues()   C

Complexity

Conditions 13
Paths 11

Size

Total Lines 63
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 40
nc 11
nop 3
dl 0
loc 63
rs 6.1128
c 0
b 0
f 0

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
namespace Digia\GraphQL\Execution;
4
5
use Digia\GraphQL\Error\GraphQLError;
6
use Digia\GraphQL\Language\AST\Node\ArgumentNode;
7
use Digia\GraphQL\Language\AST\Node\Behavior\DirectivesTrait;
8
use Digia\GraphQL\Language\AST\Node\Contract\NodeInterface;
9
use Digia\GraphQL\Language\AST\Node\DirectiveNode;
10
use Digia\GraphQL\Language\AST\Node\FieldNode;
11
use Digia\GraphQL\Language\AST\Node\NamedTypeNode;
12
use Digia\GraphQL\Language\AST\Node\VariableNode;
13
use Digia\GraphQL\Type\Definition\Contract\DirectiveInterface;
14
use Digia\GraphQL\Type\Definition\Field;
15
use Digia\GraphQL\Type\Definition\NonNullType;
16
use function Digia\GraphQL\Language\valueFromAST;
17
use function Digia\GraphQL\Util\find;
18
use function Digia\GraphQL\Util\keyMap;
19
20
/**
21
 * @param Field|DirectiveInterface $definition
22
 * @param FieldNode|DirectiveNode  $node
23
 * @param array                    $variableValues
24
 * @return array
25
 * @throws GraphQLError
26
 * @throws \Exception
27
 */
28
function getArgumentValues($definition, NodeInterface $node, array $variableValues = []): array
29
{
30
    $coercedValues       = [];
31
    $argumentDefinitions = $definition->getArguments();
32
    $argumentNodes       = $node->getArguments();
0 ignored issues
show
Bug introduced by
The method getArguments() does not exist on Digia\GraphQL\Language\A...\Contract\NodeInterface. It seems like you code against a sub-type of Digia\GraphQL\Language\A...\Contract\NodeInterface such as Digia\GraphQL\Language\AST\Node\DirectiveNode or Digia\GraphQL\Language\A...DirectiveDefinitionNode or Digia\GraphQL\Language\A...ode\FieldDefinitionNode or Digia\GraphQL\Language\AST\Node\FieldNode. ( Ignorable by Annotation )

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

32
    /** @scrutinizer ignore-call */ 
33
    $argumentNodes       = $node->getArguments();
Loading history...
33
34
    if (empty($argumentDefinitions) || empty($argumentNodes)) {
35
        return $coercedValues;
36
    }
37
38
    $argumentNodeMap = keyMap($argumentNodes, function (ArgumentNode $value) {
39
        return $value->getNameValue();
40
    });
41
42
    foreach ($argumentDefinitions as $argumentDefinition) {
43
        $name         = $argumentDefinition->getName();
44
        $argumentType = $argumentDefinition->getType();
45
        /** @var ArgumentNode $argumentNode */
46
        $argumentNode = $argumentNodeMap[$name];
47
        $defaultValue = $argumentDefinition->getDefaultValue();
48
49
        if (null === $argumentNode) {
50
            if (null === $defaultValue) {
51
                $coercedValues[$name] = $defaultValue;
52
            } elseif (!$argumentType instanceof NonNullType) {
53
                throw new GraphQLError(
54
                    sprintf('Argument "%s" of required type "%s" was not provided.', $name, $argumentType),
55
                    [$node]
56
                );
57
            }
58
        } elseif ($argumentNode instanceof VariableNode) {
59
            $variableName = $argumentNode->getNameValue();
60
61
            if (!empty($variableValues) && isset($variableValues[$variableName])) {
62
                // Note: this does not check that this variable value is correct.
63
                // This assumes that this query has been validated and the variable
64
                // usage here is of the correct type.
65
                $coercedValues[$name] = $variableValues[$variableName];
66
            } elseif (null !== $defaultValue) {
67
                $coercedValues[$name] = $defaultValue;
68
            } elseif ($argumentType instanceof NonNullType) {
69
                throw new GraphQLError(
70
                    sprintf(
71
                        'Argument "%s" of required type "%s" was provided the variable "%s" which was not provided a runtime value.',
72
                        $name,
73
                        $argumentType,
74
                        $variableName
75
                    ),
76
                    [$argumentNode->getValue()]
77
                );
78
            }
79
        } else {
80
            $valueNode = $argumentNode->getValue();
81
82
            $coercedValue = valueFromAST($valueNode, $argumentType, $variableValues);
83
84
            if (null === $coercedValue) {
85
                // Note: ValuesOfCorrectType validation should catch this before
86
                // execution. This is a runtime check to ensure execution does not
87
                // continue with an invalid argument value.
88
                throw new GraphQLError(
89
                    sprintf('Argument "%s" has invalid value %s.', $name, $valueNode),
0 ignored issues
show
Bug introduced by
It seems like $valueNode can also be of type Digia\GraphQL\Language\A...ract\ValueNodeInterface; however, parameter $args of sprintf() does only seem to accept string, 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

89
                    sprintf('Argument "%s" has invalid value %s.', $name, /** @scrutinizer ignore-type */ $valueNode),
Loading history...
90
                    [$argumentNode->getValue()]
91
                );
92
            }
93
        }
94
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
95
}
96
97
/**
98
 * @param DirectiveInterface            $directive
99
 * @param NodeInterface|DirectivesTrait $node
100
 * @param array                         $variableValues
101
 * @return array|null
102
 * @throws GraphQLError
103
 * @throws \Exception
104
 */
105
function getDirectiveValues(DirectiveInterface $directive, NodeInterface $node, array $variableValues = []): ?array
106
{
107
    $directiveNode = $node->hasDirectives()
0 ignored issues
show
Bug introduced by
The method hasDirectives() does not exist on Digia\GraphQL\Language\A...\Contract\NodeInterface. It seems like you code against a sub-type of Digia\GraphQL\Language\A...\Contract\NodeInterface such as Digia\GraphQL\Language\AST\Node\FragmentSpreadNode or Digia\GraphQL\Language\AST\Node\InlineFragmentNode or Digia\GraphQL\Language\A...EnumValueDefinitionNode or Digia\GraphQL\Language\A...nputValueDefinitionNode or Digia\GraphQL\Language\A...ode\FieldDefinitionNode or Digia\GraphQL\Language\A...de\SchemaDefinitionNode or Digia\GraphQL\Language\A...OperationDefinitionNode or Digia\GraphQL\Language\A...UnionTypeDefinitionNode or Digia\GraphQL\Language\A...\EnumTypeDefinitionNode or Digia\GraphQL\Language\A...bjectTypeDefinitionNode or Digia\GraphQL\Language\A...rfaceTypeDefinitionNode or Digia\GraphQL\Language\A...bjectTypeDefinitionNode or Digia\GraphQL\Language\A...calarTypeDefinitionNode or Digia\GraphQL\Language\A...erfaceTypeExtensionNode or Digia\GraphQL\Language\A...ScalarTypeExtensionNode or Digia\GraphQL\Language\A...\UnionTypeExtensionNode or Digia\GraphQL\Language\A...ObjectTypeExtensionNode or Digia\GraphQL\Language\A...e\EnumTypeExtensionNode or Digia\GraphQL\Language\A...ObjectTypeExtensionNode or Digia\GraphQL\Language\AST\Node\FieldNode. ( Ignorable by Annotation )

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

107
    $directiveNode = $node->/** @scrutinizer ignore-call */ hasDirectives()
Loading history...
108
        ? find($node->getDirectives(), function (NamedTypeNode $value) use ($directive) {
0 ignored issues
show
Bug introduced by
The method getDirectives() does not exist on Digia\GraphQL\Language\A...\Contract\NodeInterface. It seems like you code against a sub-type of Digia\GraphQL\Language\A...\Contract\NodeInterface such as Digia\GraphQL\Language\AST\Node\FragmentSpreadNode or Digia\GraphQL\Language\AST\Node\InlineFragmentNode or Digia\GraphQL\Language\A...EnumValueDefinitionNode or Digia\GraphQL\Language\A...nputValueDefinitionNode or Digia\GraphQL\Language\A...ode\FieldDefinitionNode or Digia\GraphQL\Language\A...de\SchemaDefinitionNode or Digia\GraphQL\Language\A...OperationDefinitionNode or Digia\GraphQL\Language\A...UnionTypeDefinitionNode or Digia\GraphQL\Language\A...\EnumTypeDefinitionNode or Digia\GraphQL\Language\A...bjectTypeDefinitionNode or Digia\GraphQL\Language\A...rfaceTypeDefinitionNode or Digia\GraphQL\Language\A...bjectTypeDefinitionNode or Digia\GraphQL\Language\A...calarTypeDefinitionNode or Digia\GraphQL\Language\A...erfaceTypeExtensionNode or Digia\GraphQL\Language\A...ScalarTypeExtensionNode or Digia\GraphQL\Language\A...\UnionTypeExtensionNode or Digia\GraphQL\Language\A...ObjectTypeExtensionNode or Digia\GraphQL\Language\A...e\EnumTypeExtensionNode or Digia\GraphQL\Language\A...ObjectTypeExtensionNode or Digia\GraphQL\Language\AST\Node\FieldNode. ( Ignorable by Annotation )

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

108
        ? find($node->/** @scrutinizer ignore-call */ getDirectives(), function (NamedTypeNode $value) use ($directive) {
Loading history...
109
            return $value->getNameValue() === $directive->getName();
110
        }) : null;
111
112
    if (null !== $directiveNode) {
113
        return getArgumentValues($directive, $directiveNode, $variableValues);
114
    }
115
116
    return null;
117
}
118