1616use Overblog \GraphQLBundle \Event \TypeLoadedEvent ;
1717use Overblog \GraphQLBundle \Resolver \ResolverMapInterface ;
1818use Overblog \GraphQLBundle \Resolver \ResolverMaps ;
19+ use Traversable ;
1920use function array_diff ;
2021use function count ;
2122use function current ;
@@ -135,24 +136,41 @@ private function decorateCustomScalarType(CustomScalarType $type, ResolverMapInt
135136
136137 private function decorateEnumType (EnumType $ type , ResolverMapInterface $ resolverMap ): void
137138 {
138- $ fieldNames = [ ];
139- foreach ( $ type -> config [ ' values ' ] as $ key => & $ value ) {
140- $ fieldName = $ value [ ' name ' ] ?? $ key ;
141- if ($ resolverMap -> isResolvable ( $ type -> name , $ fieldName )) {
142- $ value [ ' value ' ] = $ resolverMap -> resolve ( $ type -> name , $ fieldName );
139+ $ values = $ type -> config [ ' values ' ];
140+
141+ $ decoratedValues = function () use ( $ type , $ resolverMap , $ values ) {
142+ if (is_callable ( $ values )) {
143+ $ values = $ values ( );
143144 }
144- $ fieldNames [] = $ fieldName ;
145- }
146- $ unknownFields = array_diff ($ resolverMap ->covered ($ type ->name ), $ fieldNames );
147- if (!empty ($ unknownFields )) {
148- throw new InvalidArgumentException (
149- sprintf (
150- '"%s".{"%s"} defined in resolverMap, was defined in resolvers, but enum is not in schema. ' ,
151- $ type ->name ,
152- implode ('", " ' , $ unknownFields )
153- )
154- );
155- }
145+
146+ // Convert a Generator to an array so that can modify it (by reference)
147+ // and return the new array.
148+ $ values = $ values instanceof Traversable ? iterator_to_array ($ values ) : (array ) $ values ;
149+
150+ $ fieldNames = [];
151+ foreach ($ values as $ key => &$ value ) {
152+ $ fieldName = $ value ['name ' ] ?? $ key ;
153+ if ($ resolverMap ->isResolvable ($ type ->name , $ fieldName )) {
154+ $ value ['value ' ] = $ resolverMap ->resolve ($ type ->name , $ fieldName );
155+ }
156+ $ fieldNames [] = $ fieldName ;
157+ }
158+ $ unknownFields = array_diff ($ resolverMap ->covered ($ type ->name ), $ fieldNames );
159+ if (!empty ($ unknownFields )) {
160+ throw new InvalidArgumentException (
161+ sprintf (
162+ '"%s".{"%s"} defined in resolverMap, was defined in resolvers, but enum is not in schema. ' ,
163+ $ type ->name ,
164+ implode ('", " ' , $ unknownFields )
165+ )
166+ );
167+ }
168+
169+ return $ values ;
170+ };
171+
172+ /** @phpstan-ignore-next-line see https://github.com/webonyx/graphql-php/issues/1041 */
173+ $ type ->config ['values ' ] = is_callable ($ values ) ? $ decoratedValues : $ decoratedValues ();
156174 }
157175
158176 private function decorateObjectTypeFields (ObjectType $ type , array $ fieldsResolved , ResolverMapInterface $ resolverMap ): void
@@ -164,6 +182,10 @@ private function decorateObjectTypeFields(ObjectType $type, array $fieldsResolve
164182 $ fields = $ fields ();
165183 }
166184
185+ // Convert a Generator to an array so that can modify it (by reference)
186+ // and return the new array.
187+ $ fields = $ fields instanceof Traversable ? iterator_to_array ($ fields ) : (array ) $ fields ;
188+
167189 $ fieldNames = [];
168190 foreach ($ fields as $ key => &$ field ) {
169191 $ fieldName = $ field ['name ' ] ?? $ key ;
0 commit comments