Passed
Pull Request — master (#349)
by Christoffer
02:27
created

ProvidedRequiredArgumentsRule::leaveDirective()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 18
nc 4
nop 1
dl 0
loc 32
rs 9.3554
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Validation\Rule;
4
5
use Digia\GraphQL\Language\Node\ArgumentNode;
6
use Digia\GraphQL\Language\Node\DirectiveNode;
7
use Digia\GraphQL\Language\Node\FieldNode;
8
use Digia\GraphQL\Language\Visitor\VisitorResult;
9
use Digia\GraphQL\Type\Definition\NonNullType;
10
use Digia\GraphQL\Validation\ValidationException;
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 ProvidedRequiredArgumentsRule extends AbstractRule
22
{
23
    // Validate on leave to allow for deeper errors to appear first.
24
25
    /**
26
     * @inheritdoc
27
     */
28
    protected function leaveField(FieldNode $node): VisitorResult
29
    {
30
        $fieldDefinition = $this->context->getFieldDefinition();
31
32
        if (null === $fieldDefinition) {
33
            return new VisitorResult(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->context->reportError(
47
                    new ValidationException(
48
                        missingFieldArgumentMessage(
49
                            (string)$node,
50
                            (string)$argumentDefinition,
51
                            (string)$argumentType
52
                        ),
53
                        [$node]
54
                    )
55
                );
56
            }
57
        }
58
59
        return new VisitorResult($node);
60
    }
61
62
    /**
63
     * @inheritdoc
64
     */
65
    protected function leaveDirective(DirectiveNode $node): VisitorResult
66
    {
67
        $directiveDefinition = $this->context->getDirective();
68
69
        if (null === $directiveDefinition) {
70
            return new VisitorResult(null);
71
        }
72
73
        $argumentNodes   = $node->getArguments();
74
        $argumentNodeMap = keyMap($argumentNodes, function (ArgumentNode $argument) {
75
            return $argument->getNameValue();
76
        });
77
78
        foreach ($directiveDefinition->getArguments() as $argumentDefinition) {
79
            $argumentNode = $argumentNodeMap[$argumentDefinition->getName()] ?? null;
80
            $argumentType = $argumentDefinition->getType();
81
82
            if (null === $argumentNode && $argumentType instanceof NonNullType) {
83
                $this->context->reportError(
84
                    new ValidationException(
85
                        missingDirectiveArgumentMessage(
86
                            (string)$node,
87
                            (string)$argumentDefinition,
88
                            (string)$argumentType
89
                        ),
90
                        [$node]
91
                    )
92
                );
93
            }
94
        }
95
96
        return new VisitorResult($node);
97
    }
98
}
99