Completed
Pull Request — master (#45)
by Christoffer
02:10
created

NoUnusedFragmentsRule   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 56
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 56
rs 10
c 0
b 0
f 0
wmc 9

2 Methods

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