Passed
Push — master ( d010a1...aebe7d )
by Christoffer
06:05 queued 02:41
created

ProvidedNonNullArgumentsRule   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
dl 0
loc 71
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
C leaveNode() 0 66 11
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\NonNullType;
11
use function Digia\GraphQL\Util\keyMap;
12
use function Digia\GraphQL\Validation\missingDirectiveArgumentMessage;
13
use function Digia\GraphQL\Validation\missingFieldArgumentMessage;
14
15
/**
16
 * Provided required arguments
17
 *
18
 * A field or directive is only valid if all required (non-null) field arguments
19
 * have been provided.
20
 */
21
class ProvidedNonNullArgumentsRule extends AbstractRule
22
{
23
    /**
24
     * @inheritdoc
25
     */
26
    public function leaveNode(NodeInterface $node): ?NodeInterface
27
    {
28
        // Validate on leave to allow for deeper errors to appear first.
29
        if ($node instanceof FieldNode) {
30
            $fieldDefinition = $this->validationContext->getFieldDefinition();
31
32
            if (null === $fieldDefinition) {
33
                return null;
34
            }
35
36
            $argumentNodes   = $node->getArguments();
37
            $argumentNodeMap = keyMap($argumentNodes, function (ArgumentNode $argument) {
38
                return $argument->getNameValue();
39
            });
40
41
            foreach ($fieldDefinition->getArguments() as $argumentDefinition) {
42
                $argumentNode = $argumentNodeMap[$argumentDefinition->getName()] ?? null;
43
                $argumentType = $argumentDefinition->getType();
44
45
                if (null === $argumentNode && $argumentType instanceof NonNullType) {
46
                    $this->validationContext->reportError(
47
                        new ValidationException(
48
                            missingFieldArgumentMessage(
49
                                (string)$node,
50
                                (string)$argumentDefinition,
51
                                (string)$argumentType
52
                            ),
53
                            [$node]
54
                        )
55
                    );
56
                }
57
            }
58
        }
59
60
        if ($node instanceof DirectiveNode) {
61
            $directiveDefinition = $this->validationContext->getDirective();
62
63
            if (null === $directiveDefinition) {
64
                return null;
65
            }
66
67
            $argumentNodes   = $node->getArguments();
68
            $argumentNodeMap = keyMap($argumentNodes, function (ArgumentNode $argument) {
69
                return $argument->getNameValue();
70
            });
71
72
            foreach ($directiveDefinition->getArguments() as $argumentDefinition) {
73
                $argumentNode = $argumentNodeMap[$argumentDefinition->getName()] ?? null;
74
                $argumentType = $argumentDefinition->getType();
75
76
                if (null === $argumentNode && $argumentType instanceof NonNullType) {
77
                    $this->validationContext->reportError(
78
                        new ValidationException(
79
                            missingDirectiveArgumentMessage(
80
                                (string)$node,
81
                                (string)$argumentDefinition,
82
                                (string)$argumentType
83
                            ),
84
                            [$node]
85
                        )
86
                    );
87
                }
88
            }
89
        }
90
91
        return $node;
92
    }
93
}
94