9
9
use GraphQL \Type \Definition \FieldDefinition ;
10
10
use RuntimeException ;
11
11
12
+ use function array_keys ;
13
+ use function array_merge ;
14
+ use function array_unique ;
15
+
12
16
trait MutableTrait
13
17
{
14
18
/** @var string */
@@ -17,8 +21,8 @@ trait MutableTrait
17
21
/** @var array<callable> */
18
22
private $ fieldsCallables = [];
19
23
20
- /** @var FieldDefinition[]|null */
21
- private $ finalFields ;
24
+ /** @var FieldDefinition[] */
25
+ private $ fields ;
22
26
/** @var class-string<object>|null */
23
27
private $ className ;
24
28
@@ -47,15 +51,18 @@ public function addFields(callable $fields): void
47
51
*
48
52
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint
49
53
*/
50
- public function getField ($ name ): FieldDefinition
54
+ public function getField (string $ name ): FieldDefinition
51
55
{
52
- if ($ this ->status === MutableInterface::STATUS_PENDING ) {
53
- throw new RuntimeException (
54
- 'You must freeze() the MutableObjectType, ' . $ this ->className . ', before fetching its fields. '
55
- );
56
- }
56
+ $ this ->initializeFields ();
57
+
58
+ return $ this ->fields [$ name ] ?? parent ::getField ($ name );
59
+ }
60
+
61
+ public function findField (string $ name ): ?FieldDefinition
62
+ {
63
+ $ this ->initializeFields ();
57
64
58
- return parent ::getField ($ name );
65
+ return $ this -> fields [ $ name ] ?? parent ::findField ($ name );
59
66
}
60
67
61
68
/**
@@ -65,13 +72,9 @@ public function getField($name): FieldDefinition
65
72
*/
66
73
public function hasField ($ name ): bool
67
74
{
68
- if ($ this ->status === MutableInterface::STATUS_PENDING ) {
69
- throw new RuntimeException (
70
- 'You must freeze() the MutableObjectType, ' . $ this ->className . ', before fetching its fields. '
71
- );
72
- }
75
+ $ this ->initializeFields ();
73
76
74
- return parent ::hasField ($ name );
77
+ return isset ( $ this -> fields [ $ name ]) || parent ::hasField ($ name );
75
78
}
76
79
77
80
/**
@@ -81,23 +84,19 @@ public function hasField($name): bool
81
84
*/
82
85
public function getFields (): array
83
86
{
84
- if ($ this ->finalFields === null ) {
85
- if ($ this ->status === MutableInterface::STATUS_PENDING ) {
86
- throw new RuntimeException (
87
- 'You must freeze() the MutableObjectType, ' . $ this ->className . ', before fetching its fields. '
88
- );
89
- }
90
-
91
- $ this ->finalFields = parent ::getFields ();
92
- foreach ($ this ->fieldsCallables as $ fieldsCallable ) {
93
- $ this ->finalFields = FieldDefinition::defineFieldMap ($ this , $ fieldsCallable ()) + $ this ->finalFields ;
94
- }
95
- if (empty ($ this ->finalFields )) {
96
- throw NoFieldsException::create ($ this ->name );
97
- }
98
- }
87
+ $ this ->initializeFields ();
88
+
89
+ return array_merge (parent ::getFields (), $ this ->fields );
90
+ }
99
91
100
- return $ this ->finalFields ;
92
+ /**
93
+ * @return string[]
94
+ */
95
+ public function getFieldNames (): array
96
+ {
97
+ $ this ->initializeFields ();
98
+
99
+ return array_unique (array_merge (parent ::getFieldNames (), array_keys ($ this ->fields )));
101
100
}
102
101
103
102
/**
@@ -109,4 +108,26 @@ public function getMappedClassName(): ?string
109
108
{
110
109
return $ this ->className ;
111
110
}
111
+
112
+ private function initializeFields (): void
113
+ {
114
+ if ($ this ->status === MutableInterface::STATUS_PENDING ) {
115
+ throw new RuntimeException (
116
+ 'You must freeze() the MutableObjectType, ' . $ this ->className . ', before fetching its fields. '
117
+ );
118
+ }
119
+
120
+ if (isset ($ this ->fields )) {
121
+ return ;
122
+ }
123
+
124
+ $ this ->fields = [];
125
+ foreach ($ this ->fieldsCallables as $ fieldsCallable ) {
126
+ $ this ->fields = FieldDefinition::defineFieldMap ($ this , $ fieldsCallable ()) + $ this ->fields ;
127
+ }
128
+
129
+ if (empty ($ this ->fields ) && empty (parent ::getFieldNames ())) {
130
+ throw NoFieldsException::create ($ this ->name );
131
+ }
132
+ }
112
133
}
0 commit comments