Completed
Pull Request — master (#110)
by Christoffer
02:25
created

NoUnusedFragmentsRule::leaveDocument()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 8.7624
c 0
b 0
f 0
cc 5
eloc 10
nc 9
nop 1
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
    protected function enterOperationDefinition(OperationDefinitionNode $node): ?NodeInterface
34
    {
35
        $this->operationDefinitions[] = $node;
36
37
        return null;
38
    }
39
40
    /**
41
     * @inheritdoc
42
     */
43
    protected function enterFragmentDefinition(FragmentDefinitionNode $node): ?NodeInterface
44
    {
45
        $this->fragmentDefinitions[] = $node;
46
47
        return null;
48
    }
49
50
    /**
51
     * @inheritdoc
52
     */
53
    protected function leaveDocument(DocumentNode $node): ?NodeInterface
54
    {
55
        $fragmentNamesUsed = [];
56
57
        foreach ($this->operationDefinitions as $operationDefinition) {
58
            foreach ($this->context->getRecursivelyReferencedFragments($operationDefinition) as $fragmentDefinition) {
59
                $fragmentNamesUsed[$fragmentDefinition->getNameValue()] = true;
60
            }
61
        }
62
63
        foreach ($this->fragmentDefinitions as $fragmentDefinition) {
64
            $fragmentName = $fragmentDefinition->getNameValue();
65
66
            if (!isset($fragmentNamesUsed[$fragmentName])) {
67
                $this->context->reportError(
68
                    new ValidationException(unusedFragmentMessage($fragmentName), [$fragmentDefinition])
69
                );
70
            }
71
        }
72
73
        return $node;
74
    }
75
}
76