resolveFieldDescription()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 8
c 0
b 0
f 0
ccs 4
cts 4
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Definition\Loader\Annotation\FieldDecorator;
12
13
use Doctrine\Common\Annotations\Reader;
14
use Ynlo\GraphQLBundle\Annotation;
15
use Ynlo\GraphQLBundle\Definition\FieldDefinition;
16
use Ynlo\GraphQLBundle\Definition\ObjectDefinitionInterface;
17
use Ynlo\GraphQLBundle\Util\TypeUtil;
18
19
/**
20
 * Decorate a field definition using common GraphQL annotations
21
 */
22
class GraphQLFieldDefinitionDecorator implements FieldDefinitionDecoratorInterface
23
{
24
    /**
25
     * @var Reader
26
     */
27
    protected $reader;
28
29
    /**
30
     * GraphQLFieldDefinitionDecorator constructor.
31
     *
32
     * @param Reader $reader
33
     */
34 42
    public function __construct(Reader $reader)
35
    {
36 42
        $this->reader = $reader;
37 42
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42 37
    public function decorateFieldDefinition($field, FieldDefinition $definition, ObjectDefinitionInterface $objectDefinition)
43
    {
44 37
        if (!$field instanceof \ReflectionProperty && !$field instanceof \ReflectionMethod) {
45
            throw new \InvalidArgumentException('Invalid argument, expected reflection of property or method');
46
        }
47
48 37
        if (null !== $name = $this->resolveFieldName($field)) {
0 ignored issues
show
introduced by
The condition null !== $name = $this->resolveFieldName($field) is always true.
Loading history...
49 37
            $definition->setName($name);
50
        }
51
52 37
        if (null !== $type = $this->resolveFieldType($field)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $type is dead and can be removed.
Loading history...
53 33
            $definition->setType($this->resolveFieldType($field));
54 33
            $definition->setList($this->resolveFieldIsList($field));
0 ignored issues
show
Bug introduced by
It seems like $this->resolveFieldIsList($field) can also be of type null; however, parameter $list of Ynlo\GraphQLBundle\Defin...ldDefinition::setList() does only seem to accept boolean, maybe add an additional type check? ( Ignorable by Annotation )

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

54
            $definition->setList(/** @scrutinizer ignore-type */ $this->resolveFieldIsList($field));
Loading history...
55 33
            $definition->setNonNull($this->resolveFieldNonNull($field));
0 ignored issues
show
Bug introduced by
It seems like $this->resolveFieldNonNull($field) can also be of type null; however, parameter $nonNull of Ynlo\GraphQLBundle\Defin...efinition::setNonNull() does only seem to accept boolean, maybe add an additional type check? ( Ignorable by Annotation )

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

55
            $definition->setNonNull(/** @scrutinizer ignore-type */ $this->resolveFieldNonNull($field));
Loading history...
56 33
            $definition->setNonNullList($this->resolveFieldNonNullList($field));
0 ignored issues
show
Bug introduced by
It seems like $this->resolveFieldNonNullList($field) can also be of type null; however, parameter $nonNullList of Ynlo\GraphQLBundle\Defin...ition::setNonNullList() does only seem to accept boolean, maybe add an additional type check? ( Ignorable by Annotation )

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

56
            $definition->setNonNullList(/** @scrutinizer ignore-type */ $this->resolveFieldNonNullList($field));
Loading history...
57
        }
58
59 37
        if (null !== $description = $this->resolveFieldDescription($field)) {
60 10
            $definition->setDescription($description);
61
        }
62
63 37
        if ($metas = $this->resolveFieldMetas($field)) {
64
            foreach ($metas as $metaName => $metaConfig) {
65
                if ($metaConfig instanceof Annotation\Plugin\PluginConfigAnnotation) {
66
                    $metaName = $metaConfig->getName();
67
                    $metaConfig = $metaConfig->getConfig();
68
                }
69
                $existentConfig = $definition->getMeta($metaName, []);
70
                if (\is_array($existentConfig)) {
71
                    $metaConfig = array_merge($existentConfig, $metaConfig);
72
                }
73
                $definition->setMeta($metaName, $metaConfig);
74
            }
75
        }
76
77 37
        if (null !== $deprecationReason = $this->resolveFieldDeprecationReason($field)) {
78 9
            $definition->setDeprecationReason($deprecationReason);
79
        }
80
81 37
        if (null !== $customResolver = $this->resolveFieldCustomResolver($field)) {
82
            $definition->setResolver($customResolver);
83
        }
84
85 37
        if (null !== $complexity = $this->resolveFieldComplexity($field)) {
86
            $definition->setComplexity($complexity);
87
        }
88
89 37
        if ($maxConcurrentUsage = $this->resolveFieldMaxConcurrentUsage($field)) {
90
            $definition->setMaxConcurrentUsage($maxConcurrentUsage);
0 ignored issues
show
Bug introduced by
$maxConcurrentUsage of type string is incompatible with the type integer expected by parameter $maxConcurrentUsage of Ynlo\GraphQLBundle\Defin...setMaxConcurrentUsage(). ( Ignorable by Annotation )

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

90
            $definition->setMaxConcurrentUsage(/** @scrutinizer ignore-type */ $maxConcurrentUsage);
Loading history...
91
        }
92 37
    }
93
94
    /**
95
     * Get field specific annotation matching given objectDefinition
96
     *
97
     * @param \ReflectionMethod|\ReflectionProperty $prop
98
     * @param string                                $annotationClass
99
     *
100
     * @return mixed
101
     */
102 37
    protected function getFieldAnnotation($prop, string $annotationClass)
103
    {
104 37
        if ($prop instanceof \ReflectionProperty) {
105 37
            return $this->reader->getPropertyAnnotation($prop, $annotationClass);
106
        }
107
108 32
        return $this->reader->getMethodAnnotation($prop, $annotationClass);
109
    }
110
111
    /**
112
     * @param \ReflectionMethod|\ReflectionProperty $prop
113
     *
114
     * @return string|null
115
     */
116 37
    protected function resolveFieldDescription($prop): ?string
117
    {
118
        /** @var Annotation\Field $annotation */
119 37
        if ($annotation = $this->getFieldAnnotation($prop, Annotation\Field::class)) {
120 33
            return $annotation->description;
121
        }
122
123 36
        return null;
124
    }
125
126
    /**
127
     * @param \ReflectionMethod|\ReflectionProperty $prop
128
     *
129
     * @return array|null
130
     */
131 37
    protected function resolveFieldMetas($prop): ?array
132
    {
133
        /** @var Annotation\Field $annotation */
134 37
        if ($annotation = $this->getFieldAnnotation($prop, Annotation\Field::class)) {
135 33
            return $annotation->options;
136
        }
137
138 36
        return null;
139
    }
140
141
    /**
142
     * @param \ReflectionMethod|\ReflectionProperty $prop
143
     *
144
     * @return string|null
145
     */
146 37
    protected function resolveFieldCustomResolver($prop): ?string
147
    {
148
        /** @var Annotation\Field $annotation */
149 37
        if ($annotation = $this->getFieldAnnotation($prop, Annotation\Field::class)) {
150 33
            return $annotation->resolver;
151
        }
152
153 36
        return null;
154
    }
155
156
    /**
157
     * @param \ReflectionMethod|\ReflectionProperty $prop
158
     *
159
     * @return string|null
160
     */
161 37
    protected function resolveFieldDeprecationReason($prop): ?string
162
    {
163
        /** @var Annotation\Field $annotation */
164 37
        if ($annotation = $this->getFieldAnnotation($prop, Annotation\Field::class)) {
165 33
            return $annotation->deprecationReason;
166
        }
167
168 36
        return null;
169
    }
170
171
    /**
172
     * @param \ReflectionMethod|\ReflectionProperty $prop
173
     *
174
     * @return string|null
175
     */
176 37
    protected function resolveFieldComplexity($prop): ?string
177
    {
178
        /** @var Annotation\Field $annotation */
179 37
        if ($annotation = $this->getFieldAnnotation($prop, Annotation\Field::class)) {
180 33
            return $annotation->complexity;
181
        }
182
183 36
        return null;
184
    }
185
186
    /**
187
     * @param \ReflectionMethod|\ReflectionProperty $prop
188
     *
189
     * @return string|null
190
     */
191 37
    protected function resolveFieldMaxConcurrentUsage($prop): ?string
192
    {
193
        /** @var Annotation\Field $annotation */
194 37
        if ($annotation = $this->getFieldAnnotation($prop, Annotation\Field::class)) {
195 33
            return $annotation->maxConcurrentUsage;
196
        }
197
198 36
        return 0;
199
    }
200
201
    /**
202
     * @param \ReflectionMethod|\ReflectionProperty $prop
203
     *
204
     * @return bool|null
205
     */
206 33
    protected function resolveFieldNonNull($prop): ?bool
207
    {
208
        /** @var Annotation\Field $annotationField */
209 33
        $annotationField = $this->getFieldAnnotation($prop, Annotation\Field::class);
210 33
        if ($annotationField && $annotationField->type) {
211 33
            return TypeUtil::isTypeNonNull($annotationField->type);
212
        }
213
214
        return null;
215
    }
216
217
    /**
218
     * @param \ReflectionMethod|\ReflectionProperty $prop
219
     *
220
     * @return bool|null
221
     */
222 33
    protected function resolveFieldNonNullList($prop): ?bool
223
    {
224
        /** @var Annotation\Field $annotationField */
225 33
        $annotationField = $this->getFieldAnnotation($prop, Annotation\Field::class);
226 33
        if ($annotationField && $annotationField->type) {
227 33
            return TypeUtil::isTypeNonNullList($annotationField->type);
228
        }
229
230
        return null;
231
    }
232
233
    /**
234
     * @param \ReflectionMethod|\ReflectionProperty $prop
235
     *
236
     * @return bool|null
237
     */
238 33
    protected function resolveFieldIsList($prop): ?bool
239
    {
240
        /** @var Annotation\Field $annotationField */
241 33
        $annotationField = $this->getFieldAnnotation($prop, Annotation\Field::class);
242 33
        if ($annotationField && $annotationField->type) {
243 33
            return TypeUtil::isTypeList($annotationField->type);
244
        }
245
246
        return null;
247
    }
248
249
    /**
250
     * @param \ReflectionMethod|\ReflectionProperty $prop
251
     *
252
     * @return string|null
253
     */
254 37
    protected function resolveFieldType($prop): ?string
255
    {
256 37
        $type = null;
257
258
        /** @var Annotation\Field $annotationField */
259 37
        $annotationField = $this->getFieldAnnotation($prop, Annotation\Field::class);
260 37
        if ($annotationField && $annotationField->type) {
261 33
            $type = TypeUtil::normalize($annotationField->type);
262
        }
263
264 37
        return $type;
265
    }
266
267
    /**
268
     * @param \ReflectionMethod|\ReflectionProperty $prop
269
     *
270
     * @return string|null
271
     */
272 37
    protected function resolveFieldName($prop): ?string
273
    {
274
        /** @var Annotation\Field $annotation */
275 37
        if (($annotation = $this->getFieldAnnotation($prop, Annotation\Field::class)) && $annotation->name) {
276 11
            return $annotation->name;
277
        }
278
279 37
        if ($prop instanceof \ReflectionMethod) {
280 32
            if ($methodName = lcfirst(preg_replace('/^(get|set|has|is)/', null, $prop->name))) {
281 32
                return $methodName;
282
            }
283
        }
284
285 37
        return $prop->name;
286
    }
287
}
288