Passed
Push — master ( 724c6f...9da6fd )
by Rafael
06:22
created

Endpoint::getType()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5.0729

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 6
nop 1
dl 0
loc 13
ccs 6
cts 7
cp 0.8571
crap 5.0729
rs 8.8571
c 0
b 0
f 0
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\Registry;
12
13
use Ynlo\GraphQLBundle\Definition\ClassAwareDefinitionInterface;
14
use Ynlo\GraphQLBundle\Definition\DefinitionInterface;
15
use Ynlo\GraphQLBundle\Definition\InterfaceDefinition;
16
use Ynlo\GraphQLBundle\Definition\MutationDefinition;
17
use Ynlo\GraphQLBundle\Definition\QueryDefinition;
18
19
/**
20
 * Class Endpoint
21
 */
22
class Endpoint
23
{
24
    /**
25
     * @var string
26
     */
27
    protected $name;
28
29
    /**
30
     * @var DefinitionInterface[]
31
     */
32
    protected $types = [];
33
34
    /**
35
     * @var string[]
36
     */
37
    protected $typeMap = [];
38
39
    /**
40
     * @var InterfaceDefinition[]
41
     */
42
    protected $interfaces = [];
43
44
    /**
45
     * @var MutationDefinition[]
46
     */
47
    protected $mutations = [];
48
49
    /**
50
     * @var QueryDefinition[]
51
     */
52
    protected $queries = [];
53
54
    /**
55
     * Endpoint constructor.
56
     *
57
     * @param string $name
58
     */
59 2
    public function __construct(string $name)
60
    {
61 2
        $this->name = $name;
62 2
    }
63
64
    /**
65
     * @return string
66
     */
67 2
    public function getName(): string
68
    {
69 2
        return $this->name;
70
    }
71
72
    /**
73
     * @return DefinitionInterface[]
74
     */
75 2
    public function allTypes(): array
76
    {
77 2
        return $this->types;
78
    }
79
80
    /**
81
     * @param string $type
82
     *
83
     * @return null|string
84
     */
85 15
    public function getClassForType(string $type):?string
86
    {
87 15
        if (isset($this->typeMap[$type])) {
88 15
            return $this->typeMap[$type];
89
        }
90
91
        return null;
92
    }
93
94
    /**
95
     * @param string $class
96
     *
97
     * @return bool
98
     */
99 22
    public function hasTypeForClass(string $class): bool
100
    {
101 22
        return \in_array($class, $this->typeMap);
102
    }
103
104
    /**
105
     * @param string $class
106
     *
107
     * @return array|string[]
108
     */
109 22
    public function getTypesForClass(string $class): array
110
    {
111 22
        $types = array_filter(
112 22
            $this->typeMap,
113 22
            function ($val) use ($class) {
114 22
                return $val === $class;
115 22
            }
116
        );
117
118 22
        if (empty($types)) {
119
            $error = sprintf('Does not exist any valid type for class "%s"', $class);
120
            throw new \UnexpectedValueException($error);
121
        }
122
123 22
        return array_keys($types);
124
    }
125
126
    /**
127
     * Return the first type representing this class
128
     *
129
     * NOTE! a class can be represented by many types use `getTypesForClass`
130
     * to get all possible types.
131
     *
132
     * @param string $class
133
     *
134
     * @return string
135
     *
136
     * @throws \UnexpectedValueException if the class does not have any valid type
137
     */
138 22
    public function getTypeForClass(string $class): string
139
    {
140 22
        return $this->getTypesForClass($class)[0];
141
    }
142
143
    /**
144
     * Helper method to avoid in runtime
145
     * recurring all types to get only interfaces
146
     *
147
     * @return InterfaceDefinition[]
148
     */
149 22
    public function allInterfaces(): array
150
    {
151 22
        return $this->interfaces;
152
    }
153
154
    /**
155
     * @return array|MutationDefinition[]
156
     */
157 22
    public function allMutations(): array
158
    {
159 22
        return $this->mutations;
160
    }
161
162
    /**
163
     * @return array|QueryDefinition[]
164
     */
165 22
    public function allQueries(): array
166
    {
167 22
        return $this->queries;
168
    }
169
170
    /**
171
     * @param DefinitionInterface[] $types
172
     */
173 2
    public function setTypes(array $types)
174
    {
175 2
        $this->types = [];
176 2
        $this->interfaces = [];
177 2
        foreach ($types as $type) {
178 2
            $this->addType($type);
179
        }
180 2
    }
181
182
    /**
183
     * @param MutationDefinition[] $mutations
184
     */
185 2
    public function setMutations(array $mutations)
186
    {
187 2
        $this->mutations = [];
188 2
        foreach ($mutations as $mutation) {
189 2
            $this->addMutation($mutation);
190
        }
191 2
    }
192
193
    /**
194
     * @param QueryDefinition[] $queries
195
     */
196 2
    public function setQueries(array $queries)
197
    {
198 2
        $this->queries = [];
199 2
        foreach ($queries as $query) {
200 2
            $this->addQuery($query);
201
        }
202 2
    }
203
204
    /**
205
     * @param string $name
206
     *
207
     * @return bool
208
     */
209 22
    public function hasType($name): bool
210
    {
211
        //in case pass FQN class name resolve the first matching type
212 22
        if (class_exists($name) || interface_exists($name)) {
213 22
            if ($this->hasTypeForClass($name)) {
214 8
                $name = $this->getTypesForClass($name)[0];
215
            }
216
        }
217
218 22
        return array_key_exists($name, $this->types);
219
    }
220
221
    /**
222
     * @param string $name
223
     *
224
     * @return bool
225
     */
226 2
    public function hasMutation($name): bool
227
    {
228 2
        return array_key_exists($name, $this->mutations);
229
    }
230
231
    /**
232
     * @param string $name
233
     *
234
     * @return bool
235
     */
236 2
    public function hasQuery($name): bool
237
    {
238 2
        return array_key_exists($name, $this->queries);
239
    }
240
241
    /**
242
     * @param string $name
243
     *
244
     * @return Endpoint
245
     */
246
    public function removeType($name): Endpoint
247
    {
248
        if ($this->hasType($name)) {
249
            $type = $this->getType($name);
250
            if ($type instanceof InterfaceDefinition) {
251
                unset($this->interfaces[$type->getName()]);
252
            }
253
        }
254
255
        unset($this->types[$name]);
256
        if (isset($this->typeMap[$name])) {
257
            unset($this->typeMap[$name]);
258
        }
259
260
        return $this;
261
    }
262
263
    /**
264
     * @param string $name
265
     *
266
     * @return Endpoint
267
     */
268
    public function removeQuery($name): Endpoint
269
    {
270
        unset($this->queries[$name]);
271
272
        return $this;
273
    }
274
275
    /**
276
     * @param string $name
277
     *
278
     * @return Endpoint
279
     */
280
    public function removeMutation($name): Endpoint
281
    {
282
        unset($this->mutations[$name]);
283
284
        return $this;
285
    }
286
287
    /**
288
     * @param string $name
289
     *
290
     * @return DefinitionInterface
291
     *
292
     * @throws \UnexpectedValueException
293
     */
294 22
    public function getType($name)
295
    {
296 22
        if (class_exists($name) || interface_exists($name)) {
297 8
            if ($this->hasTypeForClass($name)) {
298 8
                $name = $this->getTypeForClass($name);
299
            }
300
        }
301
302 22
        if (!$this->hasType($name)) {
303
            throw new \UnexpectedValueException(sprintf('Does not exist a valid definition for "%s" type', $name));
304
        }
305
306 22
        return $this->types[$name];
307
    }
308
309
    /**
310
     * @param string $name
311
     *
312
     * @return MutationDefinition
313
     */
314
    public function getMutation($name): MutationDefinition
315
    {
316
        return $this->mutations[$name];
317
    }
318
319
    /**
320
     * @param string $name
321
     *
322
     * @return QueryDefinition
323
     */
324
    public function getQuery($name): QueryDefinition
325
    {
326
        return $this->queries[$name];
327
    }
328
329
    /**
330
     * @param DefinitionInterface $definition
331
     *
332
     * @return Endpoint
333
     */
334 2
    public function add(DefinitionInterface $definition): Endpoint
335
    {
336 2
        if ($definition instanceof MutationDefinition) {
337
            return $this->addMutation($definition);
338
        }
339
340 2
        if ($definition instanceof QueryDefinition) {
341
            return $this->addQuery($definition);
342
        }
343
344 2
        return $this->addType($definition);
345
    }
346
347
    /**
348
     * @param DefinitionInterface $type
349
     *
350
     * @return Endpoint
351
     */
352 2
    public function addType(DefinitionInterface $type): Endpoint
353
    {
354 2
        if ($this->hasType($type->getName())) {
355
            throw new \RuntimeException(sprintf('Duplicate definition for type with name "%s"', $type->getName()));
356
        }
357 2
        $this->types[$type->getName()] = $type;
358
359 2
        if ($type instanceof InterfaceDefinition) {
360 2
            $this->interfaces[$type->getName()] = $type;
361
        }
362
363 2
        if ($type instanceof ClassAwareDefinitionInterface) {
364 2
            if ($type->getClass()) {
365 2
                $class = $type->getClass();
366
                //all classes are saved without \ at the beginning
367 2
                $class = preg_replace('/^\\\\/', null, $class);
368 2
                $this->typeMap[$type->getName()] = $class;
369
            }
370
        }
371
372 2
        return $this;
373
    }
374
375
    /**
376
     * @param MutationDefinition $mutation
377
     *
378
     * @return Endpoint
379
     */
380 2
    public function addMutation(MutationDefinition $mutation): Endpoint
381
    {
382 2
        if ($this->hasMutation($mutation->getName())) {
383
            throw new \RuntimeException(sprintf('Duplicate definition for query with name "%s"', $mutation->getName()));
384
        }
385 2
        $this->mutations[$mutation->getName()] = $mutation;
386
387 2
        return $this;
388
    }
389
390
    /**
391
     * @param QueryDefinition $query
392
     *
393
     * @return Endpoint
394
     */
395 2
    public function addQuery(QueryDefinition $query): Endpoint
396
    {
397 2
        if ($this->hasQuery($query->getName())) {
398
            throw new \RuntimeException(sprintf('Duplicate definition for query with name "%s"', $query->getName()));
399
        }
400 2
        $this->queries[$query->getName()] = $query;
401
402 2
        return $this;
403
    }
404
}
405