AbstractInterfaceType::makeObjectField()
last analyzed

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 4
ccs 2
cts 2
cp 1
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
/**
15
 * @phpstan-type ArgumentConfig array{
16
 *     name: string,
17
 *     type: string,
18
 *     mode: int,
19
 *     description?: string|null,
20
 *     deprecationReason?: string|null,
21
 *     defaultValue: mixed
22
 * }
23
 * @phpstan-type FieldConfig array{
24
 *     name: string,
25
 *     type: string,
26
 *     mode: int,
27
 *     description?: string|null,
28
 *     deprecationReason?: string|null,
29
 *     arguments: array<array-key, string|ArgumentConfig>
30
 * }
31
 */
32
abstract class AbstractInterfaceType extends AbstractType implements InterfaceTypeInterface, DynamicObjectTypeInterface
33
{
34
    /**
35
     * @var iterable<array-key, string|ObjectFieldInterface|Webonyx\FieldDefinition|FieldConfig>
36
     */
37
    protected iterable $fields;
38
39
    protected array $additionalFields = [];
40
41 7
    public function getFields(): iterable
42
    {
43
        /**
44
         * @psalm-suppress RedundantPropertyInitializationCheck
45
         * @psalm-suppress RedundantCondition
46
         * @psalm-suppress TypeDoesNotContainType
47
         */
48 7
        foreach ($this->fields ?? [] as $name => $field) {
49 6
            if ($field instanceof Webonyx\FieldDefinition || $field instanceof ObjectFieldInterface) {
50 1
                yield $field;
51
52 1
                continue;
53
            }
54
55 5
            if (\is_string($field) || \is_array($field)) {
56 4
                yield $this->getObjectField($name, $field);
57
58 2
                continue;
59
            }
60
61 1
            throw new CantResolveObjectFieldException(
62 1
                'Can\'t resolve ObjectField: wrong field configuration',
63 1
            );
64
        }
65
66 4
        yield from $this->additionalFields;
67
    }
68
69 1
    public function addAdditionalField(mixed $field): static
70
    {
71 1
        $this->additionalFields[] = $field;
72
73 1
        return $this;
74
    }
75
76 4
    private function getObjectField(int|string $name, string|array $field): AbstractObjectField
77
    {
78 4
        $fieldName = $field['name'] ?? $name;
79
80 4
        if (! \is_string($fieldName)) {
81 1
            throw new CantResolveObjectFieldException(
82 1
                'Can\'t resolve ObjectField: wrong configuration - undefined name',
83 1
            );
84
        }
85
86 3
        if (\is_string($field)) {
0 ignored issues
show
introduced by
The condition is_string($field) is always false.
Loading history...
87 1
            return $this->makeObjectField($fieldName, ['type' => $field]);
88
        }
89
90 2
        if (! isset($field['type']) || ! \is_string($field['type'])) {
91 1
            throw new CantResolveObjectFieldException(
92 1
                'Can\'t resolve ObjectField: wrong configuration - undefined type',
93 1
            );
94
        }
95
96 1
        return $this->makeObjectField($fieldName, $field);
97
    }
98
99 2
    private function makeObjectField(string $name, array $field): AbstractObjectField
100
    {
101
        /** @psalm-suppress InternalClass */
102 2
        return new class($name, $field) extends AbstractAnonymousObjectField {};
103
    }
104
}
105