CompositeTypeMapper::canExtendTypeForName()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 3
1
<?php
2
3
4
namespace TheCodingMachine\GraphQL\Controllers\Mappers;
5
6
7
use function array_map;
8
use function array_merge;
9
use function array_unique;
10
use GraphQL\Type\Definition\InputObjectType;
11
use GraphQL\Type\Definition\InputType;
12
use GraphQL\Type\Definition\ObjectType;
13
use GraphQL\Type\Definition\OutputType;
14
use GraphQL\Type\Definition\Type;
15
use function is_array;
16
use function iterator_to_array;
17
use TheCodingMachine\GraphQL\Controllers\Types\MutableObjectType;
18
19
class CompositeTypeMapper implements TypeMapperInterface
20
{
21
    /**
22
     * @var TypeMapperInterface[]
23
     */
24
    private $typeMappers;
25
26
    /**
27
     * The cache of supported classes.
28
     *
29
     * @var string[]
30
     */
31
    private $supportedClasses;
32
33
    /**
34
     * @param TypeMapperInterface[] $typeMappers
35
     */
36
    public function __construct(iterable $typeMappers)
37
    {
38
        $this->typeMappers = is_array($typeMappers) ? $typeMappers: iterator_to_array($typeMappers);
39
    }
40
41
    /**
42
     * Returns true if this type mapper can map the $className FQCN to a GraphQL type.
43
     *
44
     * @param string $className
45
     * @return bool
46
     */
47
    public function canMapClassToType(string $className): bool
48
    {
49
        foreach ($this->typeMappers as $typeMapper) {
50
            if ($typeMapper->canMapClassToType($className)) {
51
                return true;
52
            }
53
        }
54
        return false;
55
    }
56
57
    /**
58
     * Maps a PHP fully qualified class name to a GraphQL type.
59
     *
60
     * @param string $className
61
     * @param OutputType|null $subType
62
     * @param RecursiveTypeMapperInterface $recursiveTypeMapper
63
     * @return MutableObjectType
64
     * @throws CannotMapTypeExceptionInterface
65
     */
66
    public function mapClassToType(string $className, ?OutputType $subType, RecursiveTypeMapperInterface $recursiveTypeMapper): MutableObjectType
67
    {
68
        foreach ($this->typeMappers as $typeMapper) {
69
            if ($typeMapper->canMapClassToType($className)) {
70
                return $typeMapper->mapClassToType($className, $subType, $recursiveTypeMapper);
71
            }
72
        }
73
        throw CannotMapTypeException::createForType($className);
74
    }
75
76
    /**
77
     * Returns the list of classes that have matching input GraphQL types.
78
     *
79
     * @return string[]
80
     */
81
    public function getSupportedClasses(): array
82
    {
83
        if ($this->supportedClasses === null) {
84
            if ($this->typeMappers === []) {
85
                $this->supportedClasses = [];
86
            } else {
87
                $supportedClassesArrays = array_map(function(TypeMapperInterface $typeMapper) { return $typeMapper->getSupportedClasses(); }, $this->typeMappers);
88
                $this->supportedClasses = array_unique(array_merge(...$supportedClassesArrays));
89
            }
90
        }
91
        return $this->supportedClasses;
92
    }
93
94
    /**
95
     * Returns true if this type mapper can map the $className FQCN to a GraphQL input type.
96
     *
97
     * @param string $className
98
     * @return bool
99
     */
100
    public function canMapClassToInputType(string $className): bool
101
    {
102
        foreach ($this->typeMappers as $typeMapper) {
103
            if ($typeMapper->canMapClassToInputType($className)) {
104
                return true;
105
            }
106
        }
107
        return false;
108
    }
109
110
    /**
111
     * Maps a PHP fully qualified class name to a GraphQL input type.
112
     *
113
     * @param string $className
114
     * @param RecursiveTypeMapperInterface $recursiveTypeMapper
115
     * @return InputObjectType
116
     * @throws CannotMapTypeExceptionInterface
117
     */
118
    public function mapClassToInputType(string $className, RecursiveTypeMapperInterface $recursiveTypeMapper): InputObjectType
119
    {
120
        foreach ($this->typeMappers as $typeMapper) {
121
            if ($typeMapper->canMapClassToInputType($className)) {
122
                return $typeMapper->mapClassToInputType($className, $recursiveTypeMapper);
123
            }
124
        }
125
        throw CannotMapTypeException::createForInputType($className);
126
    }
127
128
    /**
129
     * Returns a GraphQL type by name (can be either an input or output type)
130
     *
131
     * @param string $typeName The name of the GraphQL type
132
     * @param RecursiveTypeMapperInterface $recursiveTypeMapper
133
     * @return Type&(InputType|OutputType)
134
     */
135
    public function mapNameToType(string $typeName, RecursiveTypeMapperInterface $recursiveTypeMapper): Type
136
    {
137
        foreach ($this->typeMappers as $typeMapper) {
138
            if ($typeMapper->canMapNameToType($typeName)) {
139
                return $typeMapper->mapNameToType($typeName, $recursiveTypeMapper);
140
            }
141
        }
142
        throw CannotMapTypeException::createForName($typeName);
143
    }
144
145
    /**
146
     * Returns true if this type mapper can map the $typeName GraphQL name to a GraphQL type.
147
     *
148
     * @param string $typeName The name of the GraphQL type
149
     * @return bool
150
     */
151
    public function canMapNameToType(string $typeName): bool
152
    {
153
        foreach ($this->typeMappers as $typeMapper) {
154
            if ($typeMapper->canMapNameToType($typeName)) {
155
                return true;
156
            }
157
        }
158
        return false;
159
    }
160
161
    /**
162
     * Returns true if this type mapper can extend an existing type for the $className FQCN
163
     *
164
     * @param string $className
165
     * @param MutableObjectType $type
166
     * @return bool
167
     */
168
    public function canExtendTypeForClass(string $className, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): bool
169
    {
170
        foreach ($this->typeMappers as $typeMapper) {
171
            if ($typeMapper->canExtendTypeForClass($className, $type, $recursiveTypeMapper)) {
172
                return true;
173
            }
174
        }
175
        return false;
176
    }
177
178
    /**
179
     * Extends the existing GraphQL type that is mapped to $className.
180
     *
181
     * @param string $className
182
     * @param MutableObjectType $type
183
     * @param RecursiveTypeMapperInterface $recursiveTypeMapper
184
     * @throws CannotMapTypeExceptionInterface
185
     */
186
    public function extendTypeForClass(string $className, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): void
187
    {
188
        foreach ($this->typeMappers as $typeMapper) {
189
            if ($typeMapper->canExtendTypeForClass($className, $type, $recursiveTypeMapper)) {
190
                $typeMapper->extendTypeForClass($className, $type, $recursiveTypeMapper);
191
            }
192
        }
193
    }
194
195
    /**
196
     * Returns true if this type mapper can extend an existing type for the $typeName GraphQL type
197
     *
198
     * @param string $typeName
199
     * @param MutableObjectType $type
200
     * @return bool
201
     */
202
    public function canExtendTypeForName(string $typeName, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): bool
203
    {
204
        foreach ($this->typeMappers as $typeMapper) {
205
            if ($typeMapper->canExtendTypeForName($typeName, $type, $recursiveTypeMapper)) {
206
                return true;
207
            }
208
        }
209
        return false;
210
    }
211
212
    /**
213
     * Extends the existing GraphQL type that is mapped to the $typeName GraphQL type.
214
     *
215
     * @param string $typeName
216
     * @param MutableObjectType $type
217
     * @param RecursiveTypeMapperInterface $recursiveTypeMapper
218
     * @throws CannotMapTypeExceptionInterface
219
     */
220
    public function extendTypeForName(string $typeName, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): void
221
    {
222
        foreach ($this->typeMappers as $typeMapper) {
223
            if ($typeMapper->canExtendTypeForName($typeName, $type, $recursiveTypeMapper)) {
224
                $typeMapper->extendTypeForName($typeName, $type, $recursiveTypeMapper);
225
            }
226
        }
227
    }
228
}
229