Completed
Pull Request — master (#204)
by Ryan
11:34
created

ResolveValidator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * Copyright (c) 2015–2018 Alexandr Viniychuk <http://youshido.com>.
4
 * Copyright (c) 2015–2018 Portey Vasil <https://github.com/portey>.
5
 * Copyright (c) 2018 Ryan Parman <https://github.com/skyzyx>.
6
 * Copyright (c) 2018 Ashley Hutson <https://github.com/asheliahut>.
7
 * Copyright (c) 2015–2018 Contributors.
8
 *
9
 * http://opensource.org/licenses/MIT
10
 */
11
12
declare(strict_types=1);
13
/**
14
 * Date: 03.11.16.
15
 */
16
17
namespace Youshido\GraphQL\Validator\ResolveValidator;
18
19
use Youshido\GraphQL\Exception\ResolveException;
20
use Youshido\GraphQL\Execution\Context\ExecutionContext;
21
use Youshido\GraphQL\Execution\Request;
22
use Youshido\GraphQL\Field\FieldInterface;
23
use Youshido\GraphQL\Field\InputField;
24
use Youshido\GraphQL\Parser\Ast\Interfaces\FieldInterface as AstFieldInterface;
25 67
use Youshido\GraphQL\Type\AbstractType;
26
use Youshido\GraphQL\Type\InterfaceType\AbstractInterfaceType;
27
use Youshido\GraphQL\Type\Object\AbstractObjectType;
28 67
use Youshido\GraphQL\Type\TypeMap;
29
use Youshido\GraphQL\Type\TypeService;
30 3
use Youshido\GraphQL\Type\Union\AbstractUnionType;
31 3
32 3
class ResolveValidator implements ResolveValidatorInterface
33
{
34 67
    /** @var ExecutionContext */
35
    private $executionContext;
36
37
    /**
38 66
     * ResolveValidator constructor.
39 49
     *
40 66
     * @param ExecutionContext $executionContext
41
     */
42 66
    public function __construct(ExecutionContext $executionContext)
43 37
    {
44 1
        $this->executionContext = $executionContext;
45
    }
46
47 37
    public function assetTypeHasField(AbstractType $objectType, AstFieldInterface $ast): void
48 37
    {
49
        if (null !== $this->executionContext->getField($objectType, $ast->getName())) {
0 ignored issues
show
Compatibility introduced by
$objectType of type object<Youshido\GraphQL\Type\AbstractType> is not a sub-type of object<Youshido\GraphQL\...ect\AbstractObjectType>. It seems like you assume a child class of the class Youshido\GraphQL\Type\AbstractType to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
50 37
            return;
51 37
        }
52 35
53 16
        /** @var AbstractObjectType $objectType */
54 11
        if (!(TypeService::isObjectType($objectType) || TypeService::isInputObjectType($objectType)) || !$objectType->hasField($ast->getName())) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 146 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
55 37
            $availableFieldNames = \implode(', ', \array_map(static function (FieldInterface $field) {
56 6
                return \sprintf('"%s"', $field->getName());
57 6
            }, $objectType->getFields()));
58
59
            throw new ResolveException(\sprintf('Field "%s" not found in type "%s". Available fields are: %s', $ast->getName(), $objectType->getNamedType()->getName(), $availableFieldNames), $ast->getLocation());
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 212 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
60 34
        }
61
    }
62
63
    public function assertValidArguments(FieldInterface $field, AstFieldInterface $query, Request $request): void
64
    {
65
        $requiredArguments = \array_filter($field->getArguments(), static function (InputField $argument) {
66 34
            return TypeMap::KIND_NON_NULL === $argument->getType()->getKind();
67 34
        });
68
69
        foreach ($query->getArguments() as $astArgument) {
70
            if (!$field->hasArgument($astArgument->getName())) {
71 63
                throw new ResolveException(\sprintf('Unknown argument "%s" on field "%s"', $astArgument->getName(), $field->getName()), $astArgument->getLocation());
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 165 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
72 3
            }
73
74 61
            $argument     = $field->getArgument($astArgument->getName());
75
            $argumentType = $argument->getType()->getNullableType();
76 61
77
            switch ($argumentType->getKind()) {
78 61
                case TypeMap::KIND_ENUM:
79 4
                case TypeMap::KIND_SCALAR:
80
                case TypeMap::KIND_INPUT_OBJECT:
81
                case TypeMap::KIND_LIST:
82 59
                    if (!$argument->getType()->isValidValue($astArgument->getValue())) {
83 59
                        $error = $argument->getType()->getValidationError($astArgument->getValue()) ?: '(no details available)';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
84 3
85 3
                        throw new ResolveException(\sprintf('Not valid type for argument "%s" in query "%s": %s', $astArgument->getName(), $field->getName(), $error), $astArgument->getLocation());
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 196 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
86 3
                    }
87
88 58
                    break;
89
90 6
                default:
91
                    throw new ResolveException(\sprintf('Invalid argument type "%s"', $argumentType->getName()));
92 6
            }
93 6
94 6
            if (isset($requiredArguments[$astArgument->getName()]) || null !== $argument->getConfig()->get('defaultValue')) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 125 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
95 6
                unset($requiredArguments[$astArgument->getName()]);
96
            }
97
        }
98
99
        if (!empty($requiredArguments)) {
100
            throw new ResolveException(\sprintf('Require "%s" arguments to query "%s"', \implode(', ', \array_keys($requiredArguments)), $query->getName()));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 157 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
101
        }
102
    }
103 2
104
    public function assertValidResolvedValueForField(FieldInterface $field, $resolvedValue): void
105 2
    {
106 2
        if (null === $resolvedValue && TypeMap::KIND_NON_NULL === $field->getType()->getKind()) {
107 2
            throw new ResolveException(\sprintf('Cannot return null for non-nullable field "%s"', $field->getName()));
108
        }
109
110
        $nullableFieldType = $field->getType()->getNullableType();
111 1
112
        if (!$nullableFieldType->isValidValue($resolvedValue)) {
113
            $error = $nullableFieldType->getValidationError($resolvedValue) ?: '(no details available)';
114
115
            throw new ResolveException(\sprintf(
116
                'Not valid resolved type for field "%s": %s',
117
                $field->getName(),
118
                $error
119
            ));
120
        }
121
    }
122
123
    public function assertTypeImplementsInterface(AbstractType $type, AbstractInterfaceType $interface): void
124
    {
125
        if ($type instanceof AbstractObjectType) {
126
            foreach ($type->getInterfaces() as $typeInterface) {
127
                if ($typeInterface->getName() === $interface->getName()) {
128
                    return;
129
                }
130
            }
131
        }
132
133
        throw new ResolveException(\sprintf('Type "%s" does not implement "%s"', $type->getName(), $interface->getName()));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 123 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
134
    }
135
136
    public function assertTypeInUnionTypes(AbstractType $type, AbstractUnionType $unionType): void
137
    {
138
        foreach ($unionType->getTypes() as $unionTypeItem) {
139
            if ($unionTypeItem->getName() === $type->getName()) {
140
                return;
141
            }
142
        }
143
144
        throw new ResolveException(\sprintf('Type "%s" not exist in types of "%s"', $type->getName(), $unionType->getName()));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
145
    }
146
}
147