99use GraphQL \Type \Definition \FieldDefinition ;
1010use RuntimeException ;
1111
12+ use function array_keys ;
13+ use function array_merge ;
14+ use function array_unique ;
15+
1216trait MutableTrait
1317{
1418 /** @var string */
@@ -17,8 +21,8 @@ trait MutableTrait
1721 /** @var array<callable> */
1822 private $ fieldsCallables = [];
1923
20- /** @var FieldDefinition[]|null */
21- private $ finalFields ;
24+ /** @var FieldDefinition[] */
25+ private $ fields ;
2226 /** @var class-string<object>|null */
2327 private $ className ;
2428
@@ -47,15 +51,18 @@ public function addFields(callable $fields): void
4751 *
4852 * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint
4953 */
50- public function getField ($ name ): FieldDefinition
54+ public function getField (string $ name ): FieldDefinition
5155 {
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 ();
5764
58- return parent ::getField ($ name );
65+ return $ this -> fields [ $ name ] ?? parent ::findField ($ name );
5966 }
6067
6168 /**
@@ -65,13 +72,9 @@ public function getField($name): FieldDefinition
6572 */
6673 public function hasField ($ name ): bool
6774 {
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 ();
7376
74- return parent ::hasField ($ name );
77+ return isset ( $ this -> fields [ $ name ]) || parent ::hasField ($ name );
7578 }
7679
7780 /**
@@ -81,23 +84,19 @@ public function hasField($name): bool
8184 */
8285 public function getFields (): array
8386 {
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+ }
9991
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 )));
101100 }
102101
103102 /**
@@ -109,4 +108,26 @@ public function getMappedClassName(): ?string
109108 {
110109 return $ this ->className ;
111110 }
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+ }
112133}
0 commit comments