Completed
Push — master ( 121747...dcf58a )
by Alexandr
02:37
created

ResolveValidator   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 11

Test Coverage

Coverage 95.92%

Importance

Changes 8
Bugs 2 Features 1
Metric Value
wmc 28
lcom 0
cbo 11
dl 0
loc 91
ccs 47
cts 49
cp 0.9592
rs 10
c 8
b 2
f 1

5 Methods

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