Passed
Push — master ( 645e63...6cbe16 )
by Andrey
52s queued 14s
created

AbstractInterfaceType::getObjectField()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 10
c 0
b 0
f 0
nc 5
nop 2
dl 0
loc 20
ccs 12
cts 12
cp 1
crap 6
rs 9.2222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Andi\GraphQL\Type;
6
7
use Andi\GraphQL\Definition\Field\ObjectFieldInterface;
8
use Andi\GraphQL\Definition\Type\InterfaceTypeInterface;
9
use Andi\GraphQL\Exception\CantResolveObjectFieldException;
10
use Andi\GraphQL\Field\AbstractAnonymousObjectField;
11
use Andi\GraphQL\Field\AbstractObjectField;
12
use GraphQL\Type\Definition as Webonyx;
13
14
abstract class AbstractInterfaceType extends AbstractType implements InterfaceTypeInterface, DynamicObjectTypeInterface
15
{
16
    /**
17
     * @template A of array{name: string, type: string, typeMode: int, description: string, deprecationReason: string, defaultValue: mixed}
18
     * @template F of array{name: string, type: string, typeMode: int, description: string, deprecationReason: string, arguments: array<array-key, string|A>}
19
     *
20
     * @var iterable<array-key, string|ObjectFieldInterface|Webonyx\FieldDefinition|F>
21
     */
22
    protected iterable $fields;
23
24
    protected iterable $additionalFields = [];
25
26 7
    public function getFields(): iterable
27
    {
28 7
        foreach ($this->fields ?? [] as $name => $field) {
29 6
            if ($field instanceof Webonyx\FieldDefinition || $field instanceof ObjectFieldInterface) {
30 1
                yield $field;
31
32 1
                continue;
33
            }
34
35 5
            if (is_string($field) || is_array($field)) {
36 4
                yield $this->getObjectField($name, $field);
37
38 2
                continue;
39
            }
40
41 1
            throw new CantResolveObjectFieldException(
42 1
                'Can\'t resolve ObjectField configuration: unknown field configuration',
43 1
            );
44
        }
45
46 4
        yield from $this->additionalFields;
47
    }
48
49 1
    public function addAdditionalField(mixed $field): static
50
    {
51 1
        $this->additionalFields[] = $field;
52
53 1
        return $this;
54
    }
55
56 4
    private function getObjectField(int|string $name, string|array $field): AbstractObjectField
57
    {
58 4
        $fieldName = $field['name'] ?? $name;
59
60 4
        if (! is_string($fieldName)) {
61 1
            throw new CantResolveObjectFieldException('Can\'t resolve ObjectField configuration: undefined name');
62
        }
63
64 3
        if (is_string($field)) {
0 ignored issues
show
introduced by
The condition is_string($field) is always false.
Loading history...
65 1
            return $this->makeObjectField($fieldName, ['type' => $field]);
66
        }
67
68 2
        if (is_array($field)) {
0 ignored issues
show
introduced by
The condition is_array($field) is always true.
Loading history...
69 2
            if (! isset($field['type']) || ! is_string($field['type'])) {
70 1
                throw new CantResolveObjectFieldException(
71 1
                    'Can\'t resolve ObjectField configuration: undefined type',
72 1
                );
73
            }
74
75 1
            return $this->makeObjectField($fieldName, $field);
76
        }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 68 is false. This is incompatible with the type-hinted return Andi\GraphQL\Field\AbstractObjectField. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
77
    }
78
79 2
    private function makeObjectField(string $name, array $field): AbstractObjectField
80
    {
81 2
        return new class($name, $field) extends AbstractAnonymousObjectField {};
82
    }
83
}
84