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

FragmentsOnCompositeTypesRule::enterNode()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 1
dl 0
loc 17
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\AST\Node\FragmentDefinitionNode;
7
use Digia\GraphQL\Language\AST\Node\InlineFragmentNode;
8
use Digia\GraphQL\Language\AST\Node\NodeInterface;
9
use Digia\GraphQL\Type\Definition\CompositeTypeInterface;
10
use function Digia\GraphQL\Util\typeFromAST;
11
use function Digia\GraphQL\Validation\fragmentOnNonCompositeMessage;
12
use function Digia\GraphQL\Validation\inlineFragmentOnNonCompositeMessage;
13
14
15
/**
16
 * Fragments on composite type
17
 *
18
 * Fragments use a type condition to determine if they apply, since fragments
19
 * can only be spread into a composite type (object, interface, or union), the
20
 * type condition must also be a composite type.
21
 */
22
class FragmentsOnCompositeTypesRule extends AbstractRule
23
{
24
    /**
25
     * @inheritdoc
26
     */
27
    public function enterNode(NodeInterface $node): ?NodeInterface
28
    {
29
        if ($node instanceof InlineFragmentNode) {
30
            $this->validateFragementNode($node, function (NodeInterface $node) {
31
                /** @noinspection PhpUndefinedMethodInspection */
32
                return inlineFragmentOnNonCompositeMessage((string)$node->getTypeCondition());
0 ignored issues
show
Bug introduced by
The method getTypeCondition() does not exist on Digia\GraphQL\Language\AST\Node\NodeInterface. It seems like you code against a sub-type of Digia\GraphQL\Language\AST\Node\NodeInterface such as Digia\GraphQL\Language\AST\Node\InlineFragmentNode or Digia\GraphQL\Language\A...\FragmentDefinitionNode. ( Ignorable by Annotation )

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

32
                return inlineFragmentOnNonCompositeMessage((string)$node->/** @scrutinizer ignore-call */ getTypeCondition());
Loading history...
33
            });
34
        }
35
36
        if ($node instanceof FragmentDefinitionNode) {
37
            $this->validateFragementNode($node, function (NodeInterface $node) {
38
                /** @noinspection PhpUndefinedMethodInspection */
39
                return fragmentOnNonCompositeMessage((string)$node, (string)$node->getTypeCondition());
40
            });
41
        }
42
43
        return $node;
44
    }
45
46
    /**
47
     * @param NodeInterface|InlineFragmentNode|FragmentDefinitionNode $node
48
     * @param callable                                                $errorMessageFunction
49
     * @throws \Exception
50
     * @throws \TypeError
51
     */
52
    protected function validateFragementNode(NodeInterface $node, callable $errorMessageFunction)
53
    {
54
        $typeCondition = $node->getTypeCondition();
55
56
        if (null !== $typeCondition) {
57
            $type = typeFromAST($this->validationContext->getSchema(), $typeCondition);
58
59
            if (null !== $type && !($type instanceof CompositeTypeInterface)) {
60
                $this->validationContext->reportError(new ValidationException($errorMessageFunction($node),
61
                    [$typeCondition]));
62
            }
63
        }
64
    }
65
}
66