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

DirectivesRule::evaluate()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 61
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 61
rs 7.399
c 0
b 0
f 0
cc 7
eloc 33
nc 6
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Digia\GraphQL\SchemaValidator\Rule;
4
5
use Digia\GraphQL\Error\ValidationException;
6
use Digia\GraphQL\Language\Node\NodeAwareInterface;
7
use Digia\GraphQL\Language\Node\DirectiveNode;
8
use Digia\GraphQL\SchemaValidator\ValidationContext;
9
use Digia\GraphQL\Type\Definition\Directive;
10
use Digia\GraphQL\Type\Definition\DirectiveInterface;
11
use function Digia\GraphQL\Type\isInputType;
12
13
class DirectivesRule extends AbstractRule
14
{
15
    use ValidatesNamesTrait;
16
17
    /**
18
     * @inheritdoc
19
     */
20
    public function evaluate(): void
21
    {
22
        $directives = $this->context->getSchema()->getDirectives();
23
24
        foreach ($directives as $directive) {
25
            if (!($directive instanceof DirectiveInterface)) {
26
                $this->context->reportError(
27
                    new ValidationException(
28
                        \sprintf(
29
                            'Expected directive but got: %s.',
30
                            $directive instanceof NodeAwareInterface ? $directive->getAstNode() : $directive
0 ignored issues
show
Bug introduced by
It seems like $directive instanceof Di...tAstNode() : $directive can also be of type Digia\GraphQL\Language\Node\NodeInterface; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

30
                            /** @scrutinizer ignore-type */ $directive instanceof NodeAwareInterface ? $directive->getAstNode() : $directive
Loading history...
31
                        )
32
                    )
33
                );
34
35
                return;
36
            }
37
38
            // Ensure they are named correctly.
39
            $this->validateName($this->context, $directive);
40
41
            // TODO: Ensure proper locations.
42
43
            // Ensure the arguments are valid.
44
            $argumentNames = [];
45
46
            foreach ($directive->getArguments() as $argument) {
47
                $argumentName = $argument->getName();
48
49
                // Ensure they are named correctly.
50
                $this->validateName($this->context, $argument);
51
52
                // Ensure they are unique per directive.
53
                if (isset($argumentNames[$argumentName])) {
54
                    $this->context->reportError(
55
                        new ValidationException(
56
                            \sprintf(
57
                                'Argument @%s(%s:) can only be defined once.',
58
                                $directive->getName(),
59
                                $argumentName
60
                            ),
61
                            $this->getAllDirectiveArgumentNodes($directive, $argumentName)
62
                        )
63
                    );
64
65
                    continue;
66
                }
67
68
                $argumentNames[$argumentName] = true;
69
70
                // Ensure the type is an input type.
71
                if (!isInputType($argument->getType())) {
72
                    $this->context->reportError(
73
                        new ValidationException(
74
                            \sprintf(
75
                                'The type of @%s(%s:) must be Input Type but got: %s.',
76
                                $directive->getName(),
77
                                $argumentName,
78
                                (string)$argument->getType()
79
                            ),
80
                            $this->getAllDirectiveArgumentNodes($directive, $argumentName)
81
                        )
82
                    );
83
                }
84
            }
85
        }
86
    }
87
88
    /**
89
     * @param Directive $directive
90
     * @param string    $argumentName
91
     * @return array
92
     */
93
    protected function getAllDirectiveArgumentNodes(Directive $directive, string $argumentName)
94
    {
95
        $nodes = [];
96
97
        /** @var DirectiveNode $directiveNode */
98
        $directiveNode = $directive->getAstNode();
99
100
        if (null !== $directiveNode) {
101
            foreach ($directiveNode->getArguments() as $node) {
102
                if ($node->getNameValue() === $argumentName) {
103
                    $nodes[] = $node;
104
                }
105
            }
106
        }
107
108
        return $nodes;
109
    }
110
}
111