Passed
Pull Request — master (#190)
by Sebastian
03:29
created

leaveOperationDefinition()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 11
nc 3
nop 1
1
<?php
2
3
namespace Digia\GraphQL\Validation\Rule;
4
5
use Digia\GraphQL\Error\ValidationException;
6
use Digia\GraphQL\Language\Node\NodeInterface;
7
use Digia\GraphQL\Language\Node\OperationDefinitionNode;
8
use Digia\GraphQL\Language\Node\VariableDefinitionNode;
9
use Digia\GraphQL\Language\Node\VariableNode;
10
use function Digia\GraphQL\Validation\undefinedVariableMessage;
11
12
/**
13
 * No undefined variables
14
 *
15
 * A GraphQL operation is only valid if all variables encountered, both directly
16
 * and via fragment spreads, are defined by that operation.
17
 */
18
class NoUndefinedVariablesRule extends AbstractRule
19
{
20
21
    /**
22
     * @var array
23
     */
24
    protected $definedVariableNames;
25
26
    /**
27
     * @inheritdoc
28
     */
29
    protected function enterOperationDefinition(OperationDefinitionNode $node
30
    ): ?NodeInterface
31
    {
32
        $this->definedVariableNames = [];
33
34
        return $node;
35
    }
36
37
    /**
38
     * @inheritdoc
39
     */
40
    protected function enterVariableDefinition(VariableDefinitionNode $node
41
    ): ?NodeInterface
42
    {
43
        $this->definedVariableNames[$node->getVariable()
44
            ->getNameValue()] = true;
45
46
        return $node;
47
    }
48
49
    /**
50
     * @inheritdoc
51
     */
52
    protected function leaveOperationDefinition(OperationDefinitionNode $node
53
    ): ?NodeInterface
54
    {
55
        $usages = $this->context->getRecursiveVariableUsages($node);
56
57
        foreach ($usages as ['node' => $variableNode]) {
58
            /** @var VariableNode $variableNode */
59
            $variableName = $variableNode->getNameValue();
60
61
            if (!isset($this->definedVariableNames[$variableName])) {
62
                $operationName = $node->getName();
63
                $this->context->reportError(
64
                    new ValidationException(
65
                        undefinedVariableMessage($variableName,
66
                            $operationName ? $operationName->getValue() : null),
67
                        [$variableNode, $node]
68
                    )
69
                );
70
            }
71
        }
72
73
        return $node;
74
    }
75
}
76