Completed
Pull Request — master (#110)
by Christoffer
03:33
created

KnownArgumentNamesRule   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 9
dl 0
loc 76
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A validateField() 0 22 3
A enterArgument() 0 17 4
A validateDirective() 0 20 2
1
<?php
2
3
namespace Digia\GraphQL\Validation\Rule;
4
5
use Digia\GraphQL\Error\ValidationException;
6
use Digia\GraphQL\Language\Node\ArgumentNode;
7
use Digia\GraphQL\Language\Node\DirectiveNode;
8
use Digia\GraphQL\Language\Node\FieldNode;
9
use Digia\GraphQL\Language\Node\NodeInterface;
10
use Digia\GraphQL\Type\Definition\Argument;
11
use function Digia\GraphQL\Util\suggestionList;
12
use function Digia\GraphQL\Validation\unknownArgumentMessage;
13
use function Digia\GraphQL\Validation\unknownDirectiveArgumentMessage;
14
15
/**
16
 * Known argument names
17
 *
18
 * A GraphQL field is only valid if all supplied arguments are defined by
19
 * that field.
20
 */
21
class KnownArgumentNamesRule extends AbstractRule
22
{
23
    /**
24
     * @inheritdoc
25
     */
26
    protected function enterArgument(ArgumentNode $node): ?NodeInterface
27
    {
28
        $argumentDefinition = $this->context->getArgument();
29
30
        if (null === $argumentDefinition) {
31
            $argumentOf = $node->getAncestor();
32
33
            if ($argumentOf instanceof FieldNode) {
34
                return $this->validateField($node);
35
            }
36
37
            if ($argumentOf instanceof DirectiveNode) {
38
                return $this->validateDirective($node);
39
            }
40
        }
41
42
        return $node;
43
    }
44
45
    /**
46
     * @param NodeInterface $node
47
     * @return NodeInterface|null
48
     */
49
    protected function validateField(NodeInterface $node): ?NodeInterface
50
    {
51
        $fieldDefinition = $this->context->getFieldDefinition();
52
        $parentType      = $this->context->getParentType();
53
54
        if (null !== $fieldDefinition && null !== $parentType) {
55
            $options = array_map(function (Argument $argument) {
56
                return $argument->getName();
57
            }, $fieldDefinition->getArguments());
58
59
            /** @noinspection PhpUndefinedMethodInspection */
60
            $suggestions = suggestionList($node->getNameValue(), $options);
0 ignored issues
show
Bug introduced by
The method getNameValue() does not exist on Digia\GraphQL\Language\Node\NodeInterface. It seems like you code against a sub-type of Digia\GraphQL\Language\Node\NodeInterface such as Digia\GraphQL\Language\Node\DirectiveNode or Digia\GraphQL\Language\Node\FragmentSpreadNode or Digia\GraphQL\Language\Node\ArgumentNode or Digia\GraphQL\Language\Node\ObjectFieldNode or Digia\GraphQL\Language\Node\FieldNode or Digia\GraphQL\Language\N...DefinitionNodeInterface or Digia\GraphQL\Language\Node\VariableDefinitionNode or Digia\GraphQL\Language\Node\EnumTypeDefinitionNode or Digia\GraphQL\Language\N...DefinitionNodeInterface or Digia\GraphQL\Language\N...EnumValueDefinitionNode or Digia\GraphQL\Language\N...DirectiveDefinitionNode or Digia\GraphQL\Language\N...nputValueDefinitionNode or Digia\GraphQL\Language\Node\FieldDefinitionNode or Digia\GraphQL\Language\Node\VariableNode or Digia\GraphQL\Language\Node\NamedTypeNode or Digia\GraphQL\Language\N...ObjectTypeExtensionNode or Digia\GraphQL\Language\N...ScalarTypeExtensionNode or Digia\GraphQL\Language\Node\EnumTypeExtensionNode or Digia\GraphQL\Language\N...ObjectTypeExtensionNode or Digia\GraphQL\Language\N...erfaceTypeExtensionNode or Digia\GraphQL\Language\Node\UnionTypeExtensionNode. ( Ignorable by Annotation )

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

60
            $suggestions = suggestionList($node->/** @scrutinizer ignore-call */ getNameValue(), $options);
Loading history...
61
62
            $this->context->reportError(
63
                new ValidationException(
64
                    unknownArgumentMessage((string)$node, (string)$fieldDefinition, (string)$parentType, $suggestions),
65
                    [$node]
66
                )
67
            );
68
        }
69
70
        return $node;
71
    }
72
73
    /**
74
     * @param NodeInterface $node
75
     * @return NodeInterface|null
76
     */
77
    protected function validateDirective(NodeInterface $node): ?NodeInterface
78
    {
79
        $directive = $this->context->getDirective();
80
81
        if (null !== $directive) {
82
            $options = array_map(function (Argument $argument) {
83
                return $argument->getName();
84
            }, $directive->getArguments());
85
86
            $suggestions = suggestionList((string)$node, $options);
87
88
            $this->context->reportError(
89
                new ValidationException(
90
                    unknownDirectiveArgumentMessage((string)$node, (string)$directive, $suggestions),
91
                    [$node]
92
                )
93
            );
94
        }
95
96
        return $node;
97
    }
98
}
99