Completed
Pull Request — master (#155)
by
unknown
02:47
created

assertValidResolvedValueForField()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.2
cc 4
eloc 5
nc 3
nop 2
crap 4
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
26 59
    public function assetTypeHasField(AbstractType $objectType, AstFieldInterface $ast)
27
    {
28
        /** @var AbstractObjectType $objectType */
29 59
        if (!(TypeService::isObjectType($objectType) || TypeService::isInputObjectType($objectType)) || !$objectType->hasField($ast->getName())) {
30
            $availableFieldNames = implode(', ', array_map(function (FieldInterface $field) {
31 3
              return sprintf('"%s"', $field->getName());
32 3
            }, $objectType->getFields()));
33 3
            throw new ResolveException(sprintf('Field "%s" not found in type "%s". Available fields are: %s', $ast->getName(), $objectType->getNamedType()->getName(), $availableFieldNames), $ast->getLocation());
34
        }
35 59
    }
36
37
    public function assertValidArguments(FieldInterface $field, AstFieldInterface $query, Request $request)
38
    {
39 58
        $requiredArguments = array_filter($field->getArguments(), function (InputField $argument) {
40 43
            return $argument->getType()->getKind() === TypeMap::KIND_NON_NULL;
41 58
        });
42
43 58
        foreach ($query->getArguments() as $astArgument) {
44 33
            if (!$field->hasArgument($astArgument->getName())) {
45 1
                throw new ResolveException(sprintf('Unknown argument "%s" on field "%s"', $astArgument->getName(), $field->getName()), $astArgument->getLocation());
46
            }
47
48 33
            $argument     = $field->getArgument($astArgument->getName());
49 33
            $argumentType = $argument->getType()->getNullableType();
50
51 33
            switch ($argumentType->getKind()) {
52 33
                case TypeMap::KIND_ENUM:
53 31
                case TypeMap::KIND_SCALAR:
54 12
                case TypeMap::KIND_INPUT_OBJECT:
55 7
                case TypeMap::KIND_LIST:
56 33
                    if (!$argument->getType()->isValidValue($astArgument->getValue())) {
57 6
                        $error = $argument->getType()->getLastError() ?: '(no details available)';
58 6
                        throw new ResolveException(sprintf('Not valid type for argument "%s" in query "%s": %s', $astArgument->getName(), $field->getName(), $error), $astArgument->getLocation());
59
                    }
60
61 30
                    break;
62
63
                default:
64
                    throw new ResolveException(sprintf('Invalid argument type "%s"', $argumentType->getName()));
65
66
            }
67
68 30
            if (array_key_exists($astArgument->getName(), $requiredArguments) || $argument->getConfig()->get('defaultValue') !== null) {
69 30
                unset($requiredArguments[$astArgument->getName()]);
70
            }
71
        }
72
73 55
        if (count($requiredArguments)) {
74 3
            throw new ResolveException(sprintf('Require "%s" arguments to query "%s"', implode(', ', array_keys($requiredArguments)), $query->getName()));
75
        }
76 53
    }
77
78 53
    public function assertValidResolvedValueForField(FieldInterface $field, $resolvedValue)
79
    {
80 53
        if (null === $resolvedValue && $field->getType()->getKind() === TypeMap::KIND_NON_NULL) {
81 4
            throw new ResolveException(sprintf('Cannot return null for non-nullable field "%s"', $field->getName()));
82
        }
83
84 51
        if (!$field->getType()->getNullableType()->isValidValue($resolvedValue)) {
85 3
            throw new ResolveException(sprintf('Not valid resolved type for field "%s"', $field->getName()));
86
        }
87 50
    }
88
89 6
    public function assertTypeImplementsInterface(AbstractType $type, AbstractInterfaceType $interface)
90
    {
91 6
        if ($type instanceof AbstractObjectType) {
92 6
            foreach ($type->getInterfaces() as $typeInterface) {
93 6
                if ($typeInterface->getName() === $interface->getName()) {
94 6
                    return;
95
                }
96
            }
97
        }
98
99
        throw new ResolveException(sprintf('Type "%s" does not implement "%s"', $type->getName(), $interface->getName()));
100
    }
101
102 1
    public function assertTypeInUnionTypes(AbstractType $type, AbstractUnionType $unionType)
103
    {
104 1
        foreach ($unionType->getTypes() as $unionTypeItem) {
105 1
            if ($unionTypeItem->getName() === $type->getName()) {
106 1
                return;
107
            }
108
        }
109
110 1
        throw new ResolveException(sprintf('Type "%s" not exist in types of "%s"', $type->getName(), $unionType->getName()));
111
    }
112
113
}
114