Completed
Pull Request — master (#98)
by Christoffer
05:32
created

UniqueInputFieldNamesRule   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 6
dl 0
loc 50
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B enterNode() 0 23 4
A leaveNode() 0 7 2
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\ObjectFieldNode;
8
use Digia\GraphQL\Language\Node\ObjectValueNode;
9
use function Digia\GraphQL\Validation\duplicateInputFieldMessage;
10
11
/**
12
 * Unique input field names
13
 *
14
 * A GraphQL input object value is only valid if all supplied fields are
15
 * uniquely named.
16
 */
17
class UniqueInputFieldNamesRule extends AbstractRule
18
{
19
    /**
20
     * @var array
21
     */
22
    protected $knownInputNamesStack = [];
23
24
    /**
25
     * @var string[]
26
     */
27
    protected $knownInputNames = [];
28
29
    /**
30
     * @inheritdoc
31
     */
32
    public function enterNode(NodeInterface $node): ?NodeInterface
33
    {
34
        if ($node instanceof ObjectValueNode) {
35
            $this->knownInputNamesStack[] = $this->knownInputNames;
36
            $this->knownInputNames = [];
37
        }
38
39
        if ($node instanceof ObjectFieldNode) {
40
            $fieldName = $node->getNameValue();
41
42
            if (isset($this->knownInputNames[$fieldName])) {
43
                $this->validationContext->reportError(
44
                    new ValidationException(
45
                        duplicateInputFieldMessage($fieldName),
46
                        [$this->knownInputNames[$fieldName], $node->getName()]
47
                    )
48
                );
49
            } else {
50
                $this->knownInputNames[$fieldName] = $node->getName();
51
            }
52
        }
53
54
        return $node;
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60
    public function leaveNode(NodeInterface $node): ?NodeInterface
61
    {
62
        if ($node instanceof ObjectValueNode) {
63
            $this->knownInputNames = \array_pop($this->knownInputNamesStack);
64
        }
65
66
        return $node;
67
    }
68
69
70
}
71