Completed
Push — master ( 8c19ea...8f4b0a )
by Portey
03:08
created

ResolveValidator   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 11

Test Coverage

Coverage 90%

Importance

Changes 12
Bugs 1 Features 2
Metric Value
wmc 26
lcom 0
cbo 11
dl 0
loc 87
ccs 45
cts 50
cp 0.9
rs 10
c 12
b 1
f 2

5 Methods

Rating   Name   Duplication   Size   Complexity  
A assetTypeHasField() 0 7 4
C assertValidArguments() 0 39 11
A assertValidResolvedValueForField() 0 10 4
A assertTypeImplementsInterface() 0 12 4
A assertTypeInUnionTypes() 0 10 3
1
<?php
2
/**
3
 * Date: 03.11.16
4
 *
5
 * @author Portey Vasil <[email protected]>
6
 */
7
8
namespace Youshido\GraphQL\Validator\ResolveValidator;
9
10
11
use Youshido\GraphQL\Execution\Request;
12
use Youshido\GraphQL\Field\FieldInterface;
13
use Youshido\GraphQL\Field\InputField;
14
use Youshido\GraphQL\Parser\Ast\Interfaces\FieldInterface as AstFieldInterface;
15
use Youshido\GraphQL\Type\AbstractType;
16
use Youshido\GraphQL\Type\InterfaceType\AbstractInterfaceType;
17
use Youshido\GraphQL\Type\Object\AbstractObjectType;
18
use Youshido\GraphQL\Type\TypeMap;
19
use Youshido\GraphQL\Type\TypeService;
20
use Youshido\GraphQL\Type\Union\AbstractUnionType;
21
use Youshido\GraphQL\Validator\Exception\ResolveException;
22
23
class ResolveValidator implements ResolveValidatorInterface
24
{
25
26 32
    public function assetTypeHasField(AbstractType $objectType, AstFieldInterface $ast)
27
    {
28
        /** @var AbstractObjectType $objectType */
29 32
        if (!(TypeService::isObjectType($objectType) || TypeService::isInputObjectType($objectType)) || !$objectType->hasField($ast->getName())) {
30 3
            throw new ResolveException(sprintf('Field "%s" not found in type "%s"', $ast->getName(), $objectType->getNamedType()->getName()));
31
        }
32 32
    }
33
34
    public function assertValidArguments(FieldInterface $field, AstFieldInterface $query, Request $request)
35
    {
36 31
        $requiredArguments = array_filter($field->getArguments(), function (InputField $argument) {
37 20
            return $argument->getType()->getKind() == TypeMap::KIND_NON_NULL;
38 31
        });
39
40 31
        foreach ($query->getArguments() as $astArgument) {
41 13
            if (!$field->hasArgument($astArgument->getName())) {
42 1
                throw new ResolveException(sprintf('Unknown argument "%s" on field "%s"', $astArgument->getName(), $field->getName()));
43
            }
44
45 13
            $argument     = $field->getArgument($astArgument->getName());
46 13
            $argumentType = $argument->getType()->getNullableType();
47
48 13
            switch ($argumentType->getKind()) {
49 13
                case TypeMap::KIND_ENUM:
50 13
                case TypeMap::KIND_SCALAR:
51 13
                case TypeMap::KIND_INPUT_OBJECT:
52 13
                case TypeMap::KIND_LIST:
53 13
                    if (!$argument->getType()->isValidValue($astArgument->getValue())) {
54 3
                        throw new ResolveException(sprintf('Not valid type for argument "%s" in query "%s"', $astArgument->getName(), $field->getName()));
55
                    }
56
57 12
                    break;
58
59
                default:
60
                    throw new ResolveException(sprintf('Invalid argument type "%s"', $argumentType->getName()));
61
62 12
            }
63
64 12
            if (array_key_exists($astArgument->getName(), $requiredArguments) || $argument->getConfig()->get('default') !== null) {
65 7
                unset($requiredArguments[$astArgument->getName()]);
66 7
            }
67 30
        }
68
69 30
        if (count($requiredArguments)) {
70 2
            throw new ResolveException(sprintf('Require "%s" arguments to query "%s"', implode(', ', array_keys($requiredArguments)), $query->getName()));
71
        }
72 29
    }
73
74 29
    public function assertValidResolvedValueForField(FieldInterface $field, $resolvedValue)
75
    {
76 29
        if ($field->getType()->getKind() == TypeMap::KIND_NON_NULL && is_null($resolvedValue)) {
77 5
            throw new ResolveException(sprintf('Cannot return null for non-nullable field "%s"', $field->getName()));
78
        }
79
80 27
        if (!$field->getType()->getNullableType()->isValidValue($resolvedValue)) {
81 2
            throw new ResolveException(sprintf('Not valid resolved type for field "%s"', $field->getName()));
82
        }
83 27
    }
84
85 5
    public function assertTypeImplementsInterface(AbstractType $type, AbstractInterfaceType $interface)
86
    {
87 5
        if ($type instanceof AbstractObjectType) {
88 5
            foreach ($type->getInterfaces() as $typeInterface) {
89 5
                if ($typeInterface->getName() == $interface->getName()) {
90 5
                    return;
91
                }
92
            }
93
        }
94
95
        throw new ResolveException(sprintf('Type "%s" does not implement "%s"', $type->getName(), $interface->getName()));
96
    }
97
98 1
    public function assertTypeInUnionTypes(AbstractType $type, AbstractUnionType $unionType)
99
    {
100 1
        foreach ($unionType->getTypes() as $unionTypeItem) {
101 1
            if ($unionTypeItem->getName() == $type->getName()) {
102 1
                return;
103
            }
104 1
        }
105
106 1
        throw new ResolveException(sprintf('Type "%s" not exist in types of "%s"', $type->getName(), $unionType->getName()));
107
    }
108
109
}
110