Completed
Push — master ( e04d76...e93945 )
by Christoffer
02:13
created

NoUnusedFragmentsRule::enterNode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Validation\Rule;
4
5
use Digia\GraphQL\Error\ValidationException;
6
use Digia\GraphQL\Language\Node\DocumentNode;
7
use Digia\GraphQL\Language\Node\FragmentDefinitionNode;
8
use Digia\GraphQL\Language\Node\NodeInterface;
9
use Digia\GraphQL\Language\Node\OperationDefinitionNode;
10
use function Digia\GraphQL\Validation\unusedFragmentMessage;
11
12
/**
13
 * No unused fragments
14
 *
15
 * A GraphQL document is only valid if all fragment definitions are spread
16
 * within operations, or spread within other fragments spread within operations.
17
 */
18
class NoUnusedFragmentsRule extends AbstractRule
19
{
20
    /**
21
     * @var OperationDefinitionNode[]
22
     */
23
    protected $operationDefinitions = [];
24
25
    /**
26
     * @var FragmentDefinitionNode[]
27
     */
28
    protected $fragmentDefinitions = [];
29
30
    /**
31
     * @inheritdoc
32
     */
33
    public function enterNode(NodeInterface $node): ?NodeInterface
34
    {
35
        if ($node instanceof OperationDefinitionNode) {
36
            $this->operationDefinitions[] = $node;
37
            return null;
38
        }
39
40
        if ($node instanceof FragmentDefinitionNode) {
41
            $this->fragmentDefinitions[] = $node;
42
            return null;
43
        }
44
45
        return $node;
46
    }
47
48
    /**
49
     * @inheritdoc
50
     */
51
    public function leaveNode(NodeInterface $node): ?NodeInterface
52
    {
53
        if ($node instanceof DocumentNode) {
54
            $fragmentNamesUsed = [];
55
56
            foreach ($this->operationDefinitions as $operationDefinition) {
57
                foreach ($this->validationContext->getRecursivelyReferencedFragments($operationDefinition) as $fragmentDefinition) {
58
                    $fragmentNamesUsed[$fragmentDefinition->getNameValue()] = true;
59
                }
60
            }
61
62
            foreach ($this->fragmentDefinitions as $fragmentDefinition) {
63
                $fragmentName = $fragmentDefinition->getNameValue();
64
65
                if (!isset($fragmentNamesUsed[$fragmentName])) {
66
                    $this->validationContext->reportError(
67
                        new ValidationException(unusedFragmentMessage($fragmentName), [$fragmentDefinition])
68
                    );
69
                }
70
            }
71
        }
72
73
        return $node;
74
    }
75
}
76