1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Copyright (c) 2015–2018 Alexandr Viniychuk <http://youshido.com>. |
4
|
|
|
* Copyright (c) 2015–2018 Portey Vasil <https://github.com/portey>. |
5
|
|
|
* Copyright (c) 2018 Ryan Parman <https://github.com/skyzyx>. |
6
|
|
|
* Copyright (c) 2018 Ashley Hutson <https://github.com/asheliahut>. |
7
|
|
|
* Copyright (c) 2015–2018 Contributors. |
8
|
|
|
* |
9
|
|
|
* http://opensource.org/licenses/MIT |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
declare(strict_types=1); |
13
|
|
|
/* |
14
|
|
|
* This file is a part of GraphQL project. |
15
|
|
|
* |
16
|
|
|
* @author Alexandr Viniychuk <[email protected]> |
17
|
|
|
* created: 5/11/16 10:19 PM |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
namespace Youshido\GraphQL\Type; |
21
|
|
|
|
22
|
|
|
use Youshido\GraphQL\Type\Enum\AbstractEnumType; |
23
|
|
|
use Youshido\GraphQL\Type\InputObject\AbstractInputObjectType; |
24
|
|
|
use Youshido\GraphQL\Type\ListType\AbstractListType; |
25
|
|
|
use Youshido\GraphQL\Type\Object\AbstractObjectType; |
26
|
|
|
use Youshido\GraphQL\Type\Scalar\AbstractScalarType; |
27
|
|
|
use Youshido\GraphQL\Type\Scalar\StringType; |
28
|
|
|
|
29
|
|
|
class TypeService |
|
|
|
|
30
|
|
|
{ |
31
|
|
|
public const TYPE_CALLABLE = 'callable'; |
32
|
|
|
|
33
|
|
|
public const TYPE_GRAPHQL_TYPE = 'graphql_type'; |
34
|
|
|
|
35
|
|
|
public const TYPE_OBJECT_TYPE = 'object_type'; |
36
|
|
|
|
37
|
|
|
public const TYPE_ARRAY_OF_OBJECT_TYPES = 'array_of_object_types'; |
38
|
|
|
|
39
|
2 |
|
public const TYPE_OBJECT_INPUT_TYPE = 'object_input_type'; |
40
|
|
|
|
41
|
2 |
|
public const TYPE_LIST = 'list'; |
42
|
1 |
|
|
43
|
1 |
|
public const TYPE_BOOLEAN = TypeMap::TYPE_BOOLEAN; |
44
|
|
|
|
45
|
2 |
|
public const TYPE_STRING = TypeMap::TYPE_STRING; |
46
|
1 |
|
|
47
|
2 |
|
public const TYPE_ARRAY = 'array'; |
48
|
1 |
|
|
49
|
|
|
public const TYPE_ARRAY_OF_FIELDS_CONFIG = 'array_of_fields'; |
50
|
|
|
|
51
|
1 |
|
public const TYPE_ARRAY_OF_INPUT_FIELDS = 'array_of_inputs'; |
52
|
|
|
|
53
|
|
|
public const TYPE_ENUM_VALUES = 'array_of_values'; |
54
|
|
|
|
55
|
|
|
public const TYPE_ARRAY_OF_INTERFACES = 'array_of_interfaces'; |
56
|
|
|
|
57
|
|
|
public const TYPE_ANY = 'any'; |
58
|
2 |
|
|
59
|
|
|
public const TYPE_ANY_OBJECT = 'any_object'; |
60
|
2 |
|
|
61
|
1 |
|
public const TYPE_ANY_INPUT = 'any_input'; |
62
|
|
|
|
63
|
|
|
public static function resolveNamedType($object) |
64
|
1 |
|
{ |
65
|
|
|
if (\is_object($object) && $object instanceof AbstractType) { |
66
|
|
|
return $object->getType(); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
if (null === $object) { |
70
|
|
|
return; |
71
|
3 |
|
} |
72
|
|
|
|
73
|
3 |
|
if (\is_scalar($object)) { |
74
|
1 |
|
return new StringType(); |
75
|
|
|
} |
76
|
|
|
|
77
|
3 |
|
throw new \Exception('Invalid type'); |
78
|
|
|
} |
79
|
|
|
|
80
|
122 |
|
/** |
81
|
|
|
* @param AbstractType|mixed $type |
82
|
122 |
|
* |
83
|
106 |
|
* @return bool |
84
|
|
|
*/ |
85
|
|
|
public static function isInterface($type) |
86
|
100 |
|
{ |
87
|
|
|
if (!\is_object($type)) { |
88
|
|
|
return false; |
89
|
89 |
|
} |
90
|
|
|
|
91
|
89 |
|
return TypeMap::KIND_INTERFACE === $type->getKind(); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @param AbstractType|mixed $type |
96
|
|
|
* |
97
|
|
|
* @return bool |
98
|
|
|
*/ |
99
|
72 |
|
public static function isAbstractType($type) |
100
|
|
|
{ |
101
|
72 |
|
if (!\is_object($type)) { |
102
|
|
|
return false; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
return \in_array($type->getKind(), [TypeMap::KIND_INTERFACE, TypeMap::KIND_UNION], true); |
106
|
|
|
} |
107
|
|
|
|
108
|
6 |
|
public static function isScalarType($type) |
109
|
|
|
{ |
110
|
6 |
|
if (\is_object($type)) { |
111
|
4 |
|
return $type instanceof AbstractScalarType || $type instanceof AbstractEnumType; |
112
|
|
|
} |
113
|
4 |
|
|
114
|
3 |
|
return \in_array(\mb_strtolower($type), TypeFactory::getScalarTypesNames(), true); |
115
|
3 |
|
} |
116
|
4 |
|
|
117
|
|
|
public static function isGraphQLType($type) |
118
|
3 |
|
{ |
119
|
|
|
return $type instanceof AbstractType || self::isScalarType($type); |
120
|
|
|
} |
121
|
|
|
|
122
|
2 |
|
public static function isLeafType($type) |
123
|
|
|
{ |
124
|
2 |
|
return $type instanceof AbstractEnumType || self::isScalarType($type); |
125
|
|
|
} |
126
|
|
|
|
127
|
10 |
|
public static function isObjectType($type) |
128
|
|
|
{ |
129
|
10 |
|
return $type instanceof AbstractObjectType; |
130
|
10 |
|
} |
131
|
10 |
|
|
132
|
10 |
|
/** |
133
|
10 |
|
* @param AbstractType|mixed $type |
134
|
1 |
|
* |
135
|
|
|
* @return bool |
136
|
10 |
|
*/ |
137
|
1 |
|
public static function isInputType($type) |
138
|
|
|
{ |
139
|
|
|
if (\is_object($type)) { |
140
|
|
|
$namedType = $type->getNullableType()->getNamedType(); |
141
|
10 |
|
|
142
|
1 |
|
return ($namedType instanceof AbstractScalarType) |
143
|
1 |
|
|| ($type instanceof AbstractListType) |
144
|
|
|
|| ($namedType instanceof AbstractInputObjectType) |
145
|
|
|
|| ($namedType instanceof AbstractEnumType); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
return self::isScalarType($type); |
149
|
10 |
|
} |
150
|
|
|
|
151
|
10 |
|
public static function isInputObjectType($type) |
152
|
10 |
|
{ |
153
|
10 |
|
return $type instanceof AbstractInputObjectType; |
154
|
10 |
|
} |
155
|
|
|
|
156
|
10 |
|
public static function getPropertyValue($data, $path) |
|
|
|
|
157
|
|
|
{ |
158
|
10 |
|
if (\is_object($data)) { |
159
|
|
|
$getter = $path; |
160
|
|
|
|
161
|
|
|
if ('is' !== \mb_substr($path, 0, 2)) { |
162
|
|
|
$getter = 'get' . self::classify($path); |
163
|
|
|
|
164
|
|
|
if (!\is_callable([$data, $getter])) { |
165
|
|
|
$getter = 'is' . self::classify($path); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
if (!\is_callable([$data, $getter])) { |
169
|
|
|
$getter = self::classify($path); |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
return \is_callable([$data, $getter]) ? $data->{$getter}() : ($data->{$path} ?? null); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
return (\is_array($data) && \array_key_exists($path, $data)) ? $data[$path] : null; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
protected static function classify($text) |
180
|
|
|
{ |
181
|
|
|
$text = \explode(' ', \str_replace(['_', '/', '-', '.'], ' ', $text)); |
182
|
|
|
$textLength = \count($text); |
183
|
|
|
|
184
|
|
|
for ($i = 0; $i < $textLength; $i++) { |
185
|
|
|
$text[$i] = \ucfirst($text[$i]); |
186
|
|
|
} |
187
|
|
|
$text = \ucfirst(\implode('', $text)); |
188
|
|
|
|
189
|
|
|
return $text; |
190
|
|
|
} |
191
|
|
|
} |
192
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.