Failed Conditions
Push — master ( bdbb30...e1b4d4 )
by Vladimir
05:50
created

Type::getInternalType()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 5.667

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 13
ccs 3
cts 9
cp 0.3333
rs 10
c 0
b 0
f 0
cc 3
nc 4
nop 1
crap 5.667
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Type\Definition;
6
7
use Exception;
8
use GraphQL\Error\InvariantViolation;
9
use GraphQL\Language\AST\TypeDefinitionNode;
10
use GraphQL\Language\AST\TypeExtensionNode;
11
use GraphQL\Type\Introspection;
12
use GraphQL\Utils\Utils;
13
use JsonSerializable;
14
use ReflectionClass;
15
use Throwable;
16
use function array_keys;
17
use function array_merge;
18
use function implode;
19
use function in_array;
20
use function preg_replace;
21
use function trigger_error;
22
use const E_USER_DEPRECATED;
23
24
/**
25
 * Registry of standard GraphQL types
26
 * and a base class for all other types.
27
 */
28
abstract class Type implements JsonSerializable
29
{
30
    public const STRING  = 'String';
31
    public const INT     = 'Int';
32
    public const BOOLEAN = 'Boolean';
33
    public const FLOAT   = 'Float';
34
    public const ID      = 'ID';
35
36
    /** @var Type[] */
37
    private static $standardTypes;
38
39
    /** @var Type[] */
40
    private static $builtInTypes;
41
42
    /** @var string */
43
    public $name;
44
45
    /** @var string|null */
46
    public $description;
47
48
    /** @var TypeDefinitionNode|null */
49
    public $astNode;
50
51
    /** @var mixed[] */
52
    public $config;
53
54
    /** @var TypeExtensionNode[] */
55
    public $extensionASTNodes;
56
57
    /**
58
     * @return IDType
59
     *
60
     * @api
61
     */
62 442
    public static function id()
63
    {
64 442
        return self::getStandardType(self::ID);
65
    }
66
67
    /**
68
     * @param string $name
69
     *
70
     * @return (IDType|StringType|FloatType|IntType|BooleanType)[]|IDType|StringType|FloatType|IntType|BooleanType
71
     */
72 983
    private static function getStandardType($name = null)
73
    {
74 983
        if (self::$standardTypes === null) {
0 ignored issues
show
introduced by
The condition self::standardTypes === null is always false.
Loading history...
75
            self::$standardTypes = [
76
                self::ID      => new IDType(),
77
                self::STRING  => new StringType(),
78
                self::FLOAT   => new FloatType(),
79
                self::INT     => new IntType(),
80
                self::BOOLEAN => new BooleanType(),
81
            ];
82
        }
83
84 983
        return $name ? self::$standardTypes[$name] : self::$standardTypes;
85
    }
86
87
    /**
88
     * @return StringType
89
     *
90
     * @api
91
     */
92 836
    public static function string()
93
    {
94 836
        return self::getStandardType(self::STRING);
95
    }
96
97
    /**
98
     * @return BooleanType
99
     *
100
     * @api
101
     */
102 499
    public static function boolean()
103
    {
104 499
        return self::getStandardType(self::BOOLEAN);
105
    }
106
107
    /**
108
     * @return IntType
109
     *
110
     * @api
111
     */
112 561
    public static function int()
113
    {
114 561
        return self::getStandardType(self::INT);
115
    }
116
117
    /**
118
     * @return FloatType
119
     *
120
     * @api
121
     */
122 369
    public static function float()
123
    {
124 369
        return self::getStandardType(self::FLOAT);
125
    }
126
127
    /**
128
     * @param Type|ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType|NonNull $wrappedType
129
     *
130
     * @return ListOfType
131
     *
132
     * @api
133
     */
134 621
    public static function listOf($wrappedType)
135
    {
136 621
        return new ListOfType($wrappedType);
137
    }
138
139
    /**
140
     * @param ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType $wrappedType
141
     *
142
     * @return NonNull
143
     *
144
     * @api
145
     */
146 676
    public static function nonNull($wrappedType)
147
    {
148 676
        return new NonNull($wrappedType);
149
    }
150
151
    /**
152
     * Checks if the type is a builtin type
153
     *
154
     * @return bool
155
     */
156 106
    public static function isBuiltInType(Type $type)
157
    {
158 106
        return in_array($type->name, array_keys(self::getAllBuiltInTypes()), true);
159
    }
160
161
    /**
162
     * Returns all builtin in types including base scalar and
163
     * introspection types
164
     *
165
     * @return Type[]
166
     */
167 163
    public static function getAllBuiltInTypes()
168
    {
169 163
        if (self::$builtInTypes === null) {
0 ignored issues
show
introduced by
The condition self::builtInTypes === null is always false.
Loading history...
170 1
            self::$builtInTypes = array_merge(
171 1
                Introspection::getTypes(),
172 1
                self::getStandardTypes()
173
            );
174
        }
175
176 163
        return self::$builtInTypes;
177
    }
178
179
    /**
180
     * Returns all builtin scalar types
181
     *
182
     * @return Type[]
183
     */
184 856
    public static function getStandardTypes()
185
    {
186 856
        return self::getStandardType();
187
    }
188
189
    /**
190
     * @deprecated Use method getStandardTypes() instead
191
     *
192
     * @return Type[]
193
     */
194
    public static function getInternalTypes()
195
    {
196
        trigger_error(__METHOD__ . ' is deprecated. Use Type::getStandardTypes() instead', E_USER_DEPRECATED);
197
        return self::getStandardTypes();
198
    }
199
200
    /**
201
     * @param Type[] $types
202
     */
203 8
    public static function overrideStandardTypes(array $types)
204
    {
205 8
        $standardTypes = self::getStandardTypes();
206 8
        foreach ($types as $type) {
207 8
            Utils::invariant(
208 8
                $type instanceof Type,
209 8
                'Expecting instance of %s, got %s',
210 8
                self::class,
211 8
                Utils::printSafe($type)
212
            );
213 8
            Utils::invariant(
214 8
                isset($type->name, $standardTypes[$type->name]),
215 8
                'Expecting one of the following names for a standard type: %s, got %s',
216 8
                implode(', ', array_keys($standardTypes)),
217 8
                Utils::printSafe($type->name ?? null)
218
            );
219 8
            $standardTypes[$type->name] = $type;
220
        }
221 8
        self::$standardTypes = $standardTypes;
222 8
    }
223
224
    /**
225
     * @param Type $type
226
     *
227
     * @return bool
228
     *
229
     * @api
230
     */
231 399
    public static function isInputType($type)
232
    {
233 399
        return $type instanceof InputType &&
234
            (
235 368
                ! $type instanceof WrappingType ||
236 399
                self::getNamedType($type) instanceof InputType
237
            );
238
    }
239
240
    /**
241
     * @param Type $type
242
     *
243
     * @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType
244
     *
245
     * @api
246
     */
247 621
    public static function getNamedType($type)
248
    {
249 621
        if ($type === null) {
250 110
            return null;
251
        }
252 606
        while ($type instanceof WrappingType) {
253 312
            $type = $type->getWrappedType();
254
        }
255
256 606
        return $type;
257
    }
258
259
    /**
260
     * @param Type $type
261
     *
262
     * @return bool
263
     *
264
     * @api
265
     */
266 605
    public static function isOutputType($type)
267
    {
268 605
        return $type instanceof OutputType &&
269
            (
270 590
                ! $type instanceof WrappingType ||
271 605
                self::getNamedType($type) instanceof OutputType
272
            );
273
    }
274
275
    /**
276
     * @param Type $type
277
     *
278
     * @return bool
279
     *
280
     * @api
281
     */
282 127
    public static function isLeafType($type)
283
    {
284 127
        return $type instanceof LeafType;
285
    }
286
287
    /**
288
     * @param Type $type
289
     *
290
     * @return bool
291
     *
292
     * @api
293
     */
294 521
    public static function isCompositeType($type)
295
    {
296 521
        return $type instanceof CompositeType;
297
    }
298
299
    /**
300
     * @param Type $type
301
     *
302
     * @return bool
303
     *
304
     * @api
305
     */
306 27
    public static function isAbstractType($type)
307
    {
308 27
        return $type instanceof AbstractType;
309
    }
310
311
    /**
312
     * @param mixed $type
313
     *
314
     * @return mixed
315
     */
316 674
    public static function assertType($type)
317
    {
318 674
        Utils::invariant(
319 674
            self::isType($type),
320 674
            'Expected ' . Utils::printSafe($type) . ' to be a GraphQL type.'
321
        );
322
323 674
        return $type;
324
    }
325
326
    /**
327
     * @param Type $type
328
     *
329
     * @return bool
330
     *
331
     * @api
332
     */
333 778
    public static function isType($type)
334
    {
335 778
        return $type instanceof Type;
336
    }
337
338
    /**
339
     * @param Type $type
340
     *
341
     * @return ObjectType|InterfaceType|UnionType|ScalarType|InputObjectType|EnumType|ListOfType
342
     *
343
     * @api
344
     */
345 10
    public static function getNullableType($type)
346
    {
347 10
        return $type instanceof NonNull ? $type->getWrappedType() : $type;
348
    }
349
350
    /**
351
     * @throws InvariantViolation
352
     */
353 23
    public function assertValid()
354
    {
355 23
        Utils::assertValidName($this->name);
356 23
    }
357
358
    /**
359
     * @return string
360
     */
361 1
    public function jsonSerialize()
362
    {
363 1
        return $this->toString();
364
    }
365
366
    /**
367
     * @return string
368
     */
369 921
    public function toString()
370
    {
371 921
        return $this->name;
372
    }
373
374
    /**
375
     * @return string
376
     */
377 833
    public function __toString()
378
    {
379
        try {
380 833
            return $this->toString();
381
        } catch (Exception $e) {
382
            echo $e;
383
        } catch (Throwable $e) {
384
            echo $e;
385
        }
386
    }
387
388
    /**
389
     * @return string|null
390
     */
391 35
    protected function tryInferName()
392
    {
393 35
        if ($this->name) {
394 33
            return $this->name;
395
        }
396
397
        // If class is extended - infer name from className
398
        // QueryType -> Type
399
        // SomeOtherType -> SomeOther
400 2
        $tmp  = new ReflectionClass($this);
401 2
        $name = $tmp->getShortName();
402
403 2
        if ($tmp->getNamespaceName() !== __NAMESPACE__) {
404 1
            return preg_replace('~Type$~', '', $name);
405
        }
406
407 1
        return null;
408
    }
409
}
410