Completed
Pull Request — master (#349)
by Christoffer
04:04 queued 01:38
created

ProvidedRequiredArgumentsRule::leaveField()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 22
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 37
rs 8.9457
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
            $defaultValue = $argumentDefinition->getDefaultValue();
45
46
            if (
47
                null === $argumentNode
48
                && $argumentType instanceof NonNullType
49
                && null === $defaultValue
50
            ) {
51
                $this->context->reportError(
52
                    new ValidationException(
53
                        missingFieldArgumentMessage(
54
                            (string)$node,
55
                            (string)$argumentDefinition,
56
                            (string)$argumentType
57
                        ),
58
                        [$node]
59
                    )
60
                );
61
            }
62
        }
63
64
        return new VisitorResult($node);
65
    }
66
67
    /**
68
     * @inheritdoc
69
     */
70
    protected function leaveDirective(DirectiveNode $node): VisitorResult
71
    {
72
        $directiveDefinition = $this->context->getDirective();
73
74
        if (null === $directiveDefinition) {
75
            return new VisitorResult(null);
76
        }
77
78
        $argumentNodes   = $node->getArguments();
79
        $argumentNodeMap = keyMap($argumentNodes, function (ArgumentNode $argument) {
80
            return $argument->getNameValue();
81
        });
82
83
        foreach ($directiveDefinition->getArguments() as $argumentDefinition) {
84
            $argumentNode = $argumentNodeMap[$argumentDefinition->getName()] ?? null;
85
            $argumentType = $argumentDefinition->getType();
86
87
            if (null === $argumentNode && $argumentType instanceof NonNullType) {
88
                $this->context->reportError(
89
                    new ValidationException(
90
                        missingDirectiveArgumentMessage(
91
                            (string)$node,
92
                            (string)$argumentDefinition,
93
                            (string)$argumentType
94
                        ),
95
                        [$node]
96
                    )
97
                );
98
            }
99
        }
100
101
        return new VisitorResult($node);
102
    }
103
}
104