Completed
Push — master ( fc8b63...a31329 )
by Rafael
03:35
created

resolveFieldComplexity()   A

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)) {
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));
55 33
            $definition->setNonNull($this->resolveFieldNonNull($field));
56 33
            $definition->setNonNullList($this->resolveFieldNonNullList($field));
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 !== $complexity = $this->resolveFieldComplexity($field)) {
82
            $definition->setComplexity($complexity);
83
        }
84
85 37
        if ($maxConcurrentUsage = $this->resolveFieldMaxConcurrentUsage($field)) {
86
            $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

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