Completed
Pull Request — master (#80)
by Christoffer
02:18
created

getFieldDefinition()   D

Complexity

Conditions 10
Paths 6

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 15
nc 6
nop 3
dl 0
loc 27
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Digia\GraphQL\Util;
4
5
use Digia\GraphQL\Error\InvalidTypeException;
6
use Digia\GraphQL\Language\Node\FieldNode;
7
use Digia\GraphQL\Type\Definition\Argument;
8
use Digia\GraphQL\Type\Definition\CompositeTypeInterface;
9
use Digia\GraphQL\Type\Definition\Directive;
10
use Digia\GraphQL\Type\Definition\EnumValue;
11
use Digia\GraphQL\Type\Definition\Field;
12
use Digia\GraphQL\Type\Definition\InputTypeInterface;
13
use Digia\GraphQL\Type\Definition\InterfaceType;
14
use Digia\GraphQL\Type\Definition\ObjectType;
15
use Digia\GraphQL\Type\Definition\OutputTypeInterface;
16
use Digia\GraphQL\Type\Definition\TypeInterface;
17
use Digia\GraphQL\Type\SchemaInterface;
18
use function Digia\GraphQL\Type\SchemaMetaFieldDefinition;
19
use function Digia\GraphQL\Type\TypeMetaFieldDefinition;
20
use function Digia\GraphQL\Type\TypeNameMetaFieldDefinition;
21
22
class TypeInfo
23
{
24
    /**
25
     * @var SchemaInterface
26
     */
27
    protected $schema;
28
29
    /**
30
     * @var array|OutputTypeInterface[]
31
     */
32
    protected $typeStack = [];
33
34
    /**
35
     * @var array|CompositeTypeInterface[]
36
     */
37
    protected $parentTypeStack = [];
38
39
    /**
40
     * @var array|InputTypeInterface[]
41
     */
42
    protected $inputTypeStack = [];
43
44
    /**
45
     * @var array|Field[]
46
     */
47
    protected $fieldDefinitionStack = [];
48
49
    /**
50
     * @var Directive
51
     */
52
    protected $directive;
53
54
    /**
55
     * @var Argument
56
     */
57
    protected $argument;
58
59
    /**
60
     * @var EnumValue
61
     */
62
    protected $enumValue;
63
64
    /**
65
     * @var callable|null
66
     */
67
    protected $getFieldDefinitionFunction;
68
69
    /**
70
     * TypeInfo constructor.
71
     * @param SchemaInterface $schema
72
     * @param callable|null   $getFieldDefinitionFunction
73
     */
74
    public function __construct(
75
        SchemaInterface $schema,
76
        ?callable $getFieldDefinitionFunction = null,
77
        ?TypeInterface $initialType = null
78
    ) {
79
        $this->schema                     = $schema;
80
        $this->getFieldDefinitionFunction = null !== $getFieldDefinitionFunction
81
            ? $getFieldDefinitionFunction
82
            : function (SchemaInterface $schema, TypeInterface $parentType, FieldNode $fieldNode) {
83
                return getFieldDefinition($schema, $parentType, $fieldNode);
84
            };
85
86
        if ($initialType instanceof InputTypeInterface) {
87
            $this->inputTypeStack[] = $initialType;
88
        } elseif ($initialType instanceof CompositeTypeInterface) {
89
            $this->parentTypeStack[] = $initialType;
90
        } elseif ($initialType instanceof OutputTypeInterface) {
91
            $this->typeStack[] = $initialType;
92
        }
93
    }
94
95
    /**
96
     * @param SchemaInterface $schema
97
     * @param TypeInterface   $parentType
98
     * @param FieldNode       $fieldNode
99
     * @return Field|null
100
     */
101
    public function resolveFieldDefinition(
102
        SchemaInterface $schema,
103
        TypeInterface $parentType,
104
        FieldNode $fieldNode
105
    ): ?Field {
106
        return \call_user_func($this->getFieldDefinitionFunction, $schema, $parentType, $fieldNode);
107
    }
108
109
    /**
110
     * @param TypeInterface|null $type
111
     */
112
    public function pushType(?TypeInterface $type): void
113
    {
114
        $this->typeStack[] = $type;
115
    }
116
117
    /**
118
     *
119
     */
120
    public function popType()
121
    {
122
        array_pop($this->typeStack);
123
    }
124
125
    /**
126
     * @return TypeInterface|TypeInterface|null
127
     */
128
    public function getType(): ?TypeInterface
129
    {
130
        return $this->getFromStack($this->typeStack, 1);
131
    }
132
133
    /**
134
     * @param CompositeTypeInterface|null $type
135
     */
136
    public function pushParentType(?CompositeTypeInterface $type): void
137
    {
138
        $this->parentTypeStack[] = $type;
139
    }
140
141
    /**
142
     *
143
     */
144
    public function popParentType()
145
    {
146
        array_pop($this->parentTypeStack);
147
    }
148
149
    /**
150
     * @return TypeInterface|CompositeTypeInterface|null
151
     */
152
    public function getParentType(): ?CompositeTypeInterface
153
    {
154
        return $this->getFromStack($this->parentTypeStack, 1);
155
    }
156
157
    /**
158
     * @param TypeInterface|null $type
159
     */
160
    public function pushInputType(?TypeInterface $type): void
161
    {
162
        $this->inputTypeStack[] = $type;
163
    }
164
165
    /**
166
     *
167
     */
168
    public function popInputType()
169
    {
170
        array_pop($this->inputTypeStack);
171
    }
172
173
    /**
174
     * @return TypeInterface|null
175
     */
176
    public function getInputType(): ?TypeInterface
177
    {
178
        return $this->getFromStack($this->inputTypeStack, 1);
179
    }
180
181
    /**
182
     * @return TypeInterface|null
183
     */
184
    public function getParentInputType(): ?TypeInterface
185
    {
186
        return $this->getFromStack($this->inputTypeStack, 2);
187
    }
188
189
    /**
190
     * @param Field|null $fieldDefinition
191
     */
192
    public function pushFieldDefinition(?Field $fieldDefinition): void
193
    {
194
        $this->fieldDefinitionStack[] = $fieldDefinition;
195
    }
196
197
    /**
198
     *
199
     */
200
    public function popFieldDefinition()
201
    {
202
        array_pop($this->fieldDefinitionStack);
203
    }
204
205
    /**
206
     * @return Field|null
207
     */
208
    public function getFieldDefinition(): ?Field
209
    {
210
        return $this->getFromStack($this->fieldDefinitionStack, 1);
211
    }
212
213
    /**
214
     * @return SchemaInterface
215
     */
216
    public function getSchema(): SchemaInterface
217
    {
218
        return $this->schema;
219
    }
220
221
    /**
222
     * @return Directive|null
223
     */
224
    public function getDirective(): ?Directive
225
    {
226
        return $this->directive;
227
    }
228
229
    /**
230
     * @param Directive|null $directive
231
     */
232
    public function setDirective(?Directive $directive): void
233
    {
234
        $this->directive = $directive;
235
    }
236
237
    /**
238
     * @return Argument|null
239
     */
240
    public function getArgument(): ?Argument
241
    {
242
        return $this->argument;
243
    }
244
245
    /**
246
     * @param Argument|null $argument
247
     */
248
    public function setArgument(?Argument $argument): void
249
    {
250
        $this->argument = $argument;
251
    }
252
253
    /**
254
     * @return EnumValue|null
255
     */
256
    public function getEnumValue(): ?EnumValue
257
    {
258
        return $this->enumValue;
259
    }
260
261
    /**
262
     * @param EnumValue|null $enumValue
263
     */
264
    public function setEnumValue(?EnumValue $enumValue): void
265
    {
266
        $this->enumValue = $enumValue;
267
    }
268
269
    /**
270
     * @param array $stack
271
     * @param int   $depth
272
     * @return mixed|null
273
     */
274
    protected function getFromStack(array $stack, int $depth)
275
    {
276
        $count = count($stack);
277
        return $count >= $depth ? $stack[$count - $depth] : null;
278
    }
279
}
280
281
/**
282
 * @param SchemaInterface $schema
283
 * @param TypeInterface   $parentType
284
 * @param FieldNode       $fieldNode
285
 * @return Field|null
286
 * @throws InvalidTypeException
287
 */
288
function getFieldDefinition(SchemaInterface $schema, TypeInterface $parentType, FieldNode $fieldNode): ?Field
289
{
290
    $name = $fieldNode->getNameValue();
291
292
    $schemaDefinition = SchemaMetaFieldDefinition();
293
    if ($name === $schemaDefinition->getName() && $schema->getQuery() === $parentType) {
0 ignored issues
show
introduced by
The condition $schema->getQuery() === $parentType is always false.
Loading history...
294
        return $schemaDefinition;
295
    }
296
297
    $typeDefinition = TypeMetaFieldDefinition();
298
    if ($name === $typeDefinition->getName() && $schema->getQuery() === $parentType) {
0 ignored issues
show
introduced by
The condition $schema->getQuery() === $parentType is always false.
Loading history...
299
        return $typeDefinition;
300
    }
301
302
    $typeNameDefinition = TypeNameMetaFieldDefinition();
303
    if ($name === $typeNameDefinition->getName() && $parentType instanceof CompositeTypeInterface) {
304
        return $typeNameDefinition;
305
    }
306
307
    if ($parentType instanceof ObjectType || $parentType instanceof InterfaceType) {
308
        $fields = $parentType->getFields();
309
        if (isset($fields[$name])) {
310
            return $fields[$name];
311
        }
312
    }
313
314
    return null;
315
}
316