13
13
14
14
namespace ApiPlatform \Core \GraphQl \Type ;
15
15
16
+ use ApiPlatform \Core \Exception \ResourceClassNotFoundException ;
16
17
use ApiPlatform \Core \GraphQl \Resolver \Factory \ResolverFactoryInterface ;
17
18
use ApiPlatform \Core \GraphQl \Type \Definition \TypeInterface ;
18
19
use ApiPlatform \Core \Metadata \Property \Factory \PropertyMetadataFactoryInterface ;
@@ -89,14 +90,14 @@ public function getQueryFields(string $resourceClass, ResourceMetadata $resource
89
90
90
91
$ deprecationReason = $ resourceMetadata ->getGraphqlAttribute ($ queryName , 'deprecation_reason ' , '' , true );
91
92
92
- if (false !== $ itemConfiguration && $ fieldConfiguration = $ this ->getResourceFieldConfiguration ($ resourceClass , $ resourceMetadata , null , null , $ deprecationReason , new Type (Type::BUILTIN_TYPE_OBJECT , true , $ resourceClass ), $ resourceClass , false , $ queryName , null )) {
93
+ if (false !== $ itemConfiguration && $ fieldConfiguration = $ this ->getResourceFieldConfiguration (null , null , $ deprecationReason , new Type (Type::BUILTIN_TYPE_OBJECT , true , $ resourceClass ), $ resourceClass , false , $ queryName , null )) {
93
94
$ args = $ this ->resolveResourceArgs ($ itemConfiguration ['args ' ] ?? [], $ queryName , $ shortName );
94
95
$ itemConfiguration ['args ' ] = $ args ?: $ itemConfiguration ['args ' ] ?? ['id ' => ['type ' => GraphQLType::nonNull (GraphQLType::id ())]];
95
96
96
97
$ queryFields [$ fieldName ] = array_merge ($ fieldConfiguration , $ itemConfiguration );
97
98
}
98
99
99
- if (false !== $ collectionConfiguration && $ fieldConfiguration = $ this ->getResourceFieldConfiguration ($ resourceClass , $ resourceMetadata , null , null , $ deprecationReason , new Type (Type::BUILTIN_TYPE_OBJECT , false , null , true , null , new Type (Type::BUILTIN_TYPE_OBJECT , false , $ resourceClass )), $ resourceClass , false , $ queryName , null )) {
100
+ if (false !== $ collectionConfiguration && $ fieldConfiguration = $ this ->getResourceFieldConfiguration (null , null , $ deprecationReason , new Type (Type::BUILTIN_TYPE_OBJECT , false , null , true , null , new Type (Type::BUILTIN_TYPE_OBJECT , false , $ resourceClass )), $ resourceClass , false , $ queryName , null )) {
100
101
$ args = $ this ->resolveResourceArgs ($ collectionConfiguration ['args ' ] ?? [], $ queryName , $ shortName );
101
102
$ collectionConfiguration ['args ' ] = $ args ?: $ collectionConfiguration ['args ' ] ?? $ fieldConfiguration ['args ' ];
102
103
@@ -116,8 +117,8 @@ public function getMutationFields(string $resourceClass, ResourceMetadata $resou
116
117
$ resourceType = new Type (Type::BUILTIN_TYPE_OBJECT , true , $ resourceClass );
117
118
$ deprecationReason = $ resourceMetadata ->getGraphqlAttribute ($ mutationName , 'deprecation_reason ' , '' , true );
118
119
119
- if ($ fieldConfiguration = $ this ->getResourceFieldConfiguration ($ resourceClass , $ resourceMetadata , null , ucfirst ("{$ mutationName }s a $ shortName. " ), $ deprecationReason , $ resourceType , $ resourceClass , false , null , $ mutationName )) {
120
- $ fieldConfiguration ['args ' ] += ['input ' => $ this ->getResourceFieldConfiguration ($ resourceClass , $ resourceMetadata , null , null , $ deprecationReason , $ resourceType , $ resourceClass , true , null , $ mutationName )];
120
+ if ($ fieldConfiguration = $ this ->getResourceFieldConfiguration (null , ucfirst ("{$ mutationName }s a $ shortName. " ), $ deprecationReason , $ resourceType , $ resourceClass , false , null , $ mutationName )) {
121
+ $ fieldConfiguration ['args ' ] += ['input ' => $ this ->getResourceFieldConfiguration (null , null , $ deprecationReason , $ resourceType , $ resourceClass , true , null , $ mutationName )];
121
122
122
123
if (!$ this ->typeBuilder ->isCollection ($ resourceType )) {
123
124
$ fieldConfiguration ['resolve ' ] = ($ this ->itemMutationResolverFactory )($ resourceClass , null , $ mutationName );
@@ -175,15 +176,9 @@ public function getResourceObjectTypeFields(?string $resourceClass, ResourceMeta
175
176
continue ;
176
177
}
177
178
178
- $ rootResource = $ resourceClass ;
179
- if (null !== $ propertyMetadata ->getSubresource ()) {
180
- $ resourceClass = $ propertyMetadata ->getSubresource ()->getResourceClass ();
181
- $ resourceMetadata = $ this ->resourceMetadataFactory ->create ($ resourceClass );
182
- }
183
- if ($ fieldConfiguration = $ this ->getResourceFieldConfiguration ($ resourceClass , $ resourceMetadata , $ property , $ propertyMetadata ->getDescription (), $ propertyMetadata ->getAttribute ('deprecation_reason ' , '' ), $ propertyType , $ rootResource , $ input , $ queryName , $ mutationName , $ depth )) {
179
+ if ($ fieldConfiguration = $ this ->getResourceFieldConfiguration ($ property , $ propertyMetadata ->getDescription (), $ propertyMetadata ->getAttribute ('deprecation_reason ' , '' ), $ propertyType , $ resourceClass , $ input , $ queryName , $ mutationName , $ depth )) {
184
180
$ fields ['id ' === $ property ? '_id ' : $ property ] = $ fieldConfiguration ;
185
181
}
186
- $ resourceClass = $ rootResource ;
187
182
}
188
183
}
189
184
@@ -215,19 +210,27 @@ public function resolveResourceArgs(array $args, string $operationName, string $
215
210
*
216
211
* @see http://webonyx.github.io/graphql-php/type-system/object-types/
217
212
*/
218
- private function getResourceFieldConfiguration (string $ resourceClass , ResourceMetadata $ resourceMetadata , ?string $ property , ?string $ fieldDescription , string $ deprecationReason , Type $ type , string $ rootResource , bool $ input , ?string $ queryName , ?string $ mutationName , int $ depth = 0 ): ?array
213
+ private function getResourceFieldConfiguration (?string $ property , ?string $ fieldDescription , string $ deprecationReason , Type $ type , string $ rootResource , bool $ input , ?string $ queryName , ?string $ mutationName , int $ depth = 0 ): ?array
219
214
{
220
215
try {
221
- if (null === $ graphqlType = $ this ->convertType ($ type , $ input , $ queryName , $ mutationName , $ resourceClass , $ property , $ depth )) {
216
+ $ resourceClass = $ this ->typeBuilder ->isCollection ($ type ) && ($ collectionValueType = $ type ->getCollectionValueType ()) ? $ collectionValueType ->getClassName () : $ type ->getClassName ();
217
+
218
+ if (null === $ graphqlType = $ this ->convertType ($ type , $ input , $ queryName , $ mutationName , $ resourceClass ?? '' , $ rootResource , $ property , $ depth )) {
222
219
return null ;
223
220
}
224
221
225
222
$ graphqlWrappedType = $ graphqlType instanceof WrappingType ? $ graphqlType ->getWrappedType () : $ graphqlType ;
226
223
$ isStandardGraphqlType = \in_array ($ graphqlWrappedType , GraphQLType::getStandardTypes (), true );
227
224
if ($ isStandardGraphqlType ) {
228
- $ className = '' ;
229
- } else {
230
- $ className = $ this ->typeBuilder ->isCollection ($ type ) && ($ collectionValueType = $ type ->getCollectionValueType ()) ? $ collectionValueType ->getClassName () : $ type ->getClassName ();
225
+ $ resourceClass = '' ;
226
+ }
227
+
228
+ $ resourceMetadata = null ;
229
+ if (!empty ($ resourceClass )) {
230
+ try {
231
+ $ resourceMetadata = $ this ->resourceMetadataFactory ->create ($ resourceClass );
232
+ } catch (ResourceClassNotFoundException $ e ) {
233
+ }
231
234
}
232
235
233
236
$ args = [];
@@ -253,40 +256,15 @@ private function getResourceFieldConfiguration(string $resourceClass, ResourceMe
253
256
];
254
257
}
255
258
256
- foreach ($ resourceMetadata ->getGraphqlAttribute ($ queryName ?? 'query ' , 'filters ' , [], true ) as $ filterId ) {
257
- if (null === $ this ->filterLocator || !$ this ->filterLocator ->has ($ filterId )) {
258
- continue ;
259
- }
260
-
261
- foreach ($ this ->filterLocator ->get ($ filterId )->getDescription ($ resourceClass ) as $ key => $ value ) {
262
- $ nullable = isset ($ value ['required ' ]) ? !$ value ['required ' ] : true ;
263
- $ filterType = \in_array ($ value ['type ' ], Type::$ builtinTypes , true ) ? new Type ($ value ['type ' ], $ nullable ) : new Type ('object ' , $ nullable , $ value ['type ' ]);
264
- $ graphqlFilterType = $ this ->convertType ($ filterType , false , $ queryName , $ mutationName , $ resourceClass , $ property , $ depth );
265
-
266
- if ('[] ' === substr ($ key , -2 )) {
267
- $ graphqlFilterType = GraphQLType::listOf ($ graphqlFilterType );
268
- $ key = substr ($ key , 0 , -2 ).'_list ' ;
269
- }
270
-
271
- parse_str ($ key , $ parsed );
272
- if (\array_key_exists ($ key , $ parsed ) && \is_array ($ parsed [$ key ])) {
273
- $ parsed = [$ key => '' ];
274
- }
275
- array_walk_recursive ($ parsed , function (&$ value ) use ($ graphqlFilterType ) {
276
- $ value = $ graphqlFilterType ;
277
- });
278
- $ args = $ this ->mergeFilterArgs ($ args , $ parsed , $ resourceMetadata , $ key );
279
- }
280
- }
281
- $ args = $ this ->convertFilterArgsToTypes ($ args );
259
+ $ args = $ this ->getFilterArgs ($ args , $ resourceClass , $ resourceMetadata , $ rootResource , $ property , $ queryName , $ mutationName , $ depth );
282
260
}
283
261
284
262
if ($ isStandardGraphqlType || $ input ) {
285
263
$ resolve = null ;
286
264
} elseif ($ this ->typeBuilder ->isCollection ($ type )) {
287
- $ resolve = ($ this ->collectionResolverFactory )($ className , $ rootResource , $ queryName );
265
+ $ resolve = ($ this ->collectionResolverFactory )($ resourceClass , $ rootResource , $ queryName );
288
266
} else {
289
- $ resolve = ($ this ->itemResolverFactory )($ className , $ rootResource , $ queryName );
267
+ $ resolve = ($ this ->itemResolverFactory )($ resourceClass , $ rootResource , $ queryName );
290
268
}
291
269
292
270
return [
@@ -303,6 +281,41 @@ private function getResourceFieldConfiguration(string $resourceClass, ResourceMe
303
281
return null ;
304
282
}
305
283
284
+ private function getFilterArgs (array $ args , ?string $ resourceClass , ?ResourceMetadata $ resourceMetadata , string $ rootResource , ?string $ property , ?string $ queryName , ?string $ mutationName , int $ depth ): array
285
+ {
286
+ if (null === $ resourceMetadata || null === $ resourceClass ) {
287
+ return $ args ;
288
+ }
289
+
290
+ foreach ($ resourceMetadata ->getGraphqlAttribute ($ queryName ?? 'query ' , 'filters ' , [], true ) as $ filterId ) {
291
+ if (null === $ this ->filterLocator || !$ this ->filterLocator ->has ($ filterId )) {
292
+ continue ;
293
+ }
294
+
295
+ foreach ($ this ->filterLocator ->get ($ filterId )->getDescription ($ resourceClass ) as $ key => $ value ) {
296
+ $ nullable = isset ($ value ['required ' ]) ? !$ value ['required ' ] : true ;
297
+ $ filterType = \in_array ($ value ['type ' ], Type::$ builtinTypes , true ) ? new Type ($ value ['type ' ], $ nullable ) : new Type ('object ' , $ nullable , $ value ['type ' ]);
298
+ $ graphqlFilterType = $ this ->convertType ($ filterType , false , $ queryName , $ mutationName , $ resourceClass , $ rootResource , $ property , $ depth );
299
+
300
+ if ('[] ' === substr ($ key , -2 )) {
301
+ $ graphqlFilterType = GraphQLType::listOf ($ graphqlFilterType );
302
+ $ key = substr ($ key , 0 , -2 ).'_list ' ;
303
+ }
304
+
305
+ parse_str ($ key , $ parsed );
306
+ if (\array_key_exists ($ key , $ parsed ) && \is_array ($ parsed [$ key ])) {
307
+ $ parsed = [$ key => '' ];
308
+ }
309
+ array_walk_recursive ($ parsed , function (&$ value ) use ($ graphqlFilterType ) {
310
+ $ value = $ graphqlFilterType ;
311
+ });
312
+ $ args = $ this ->mergeFilterArgs ($ args , $ parsed , $ resourceMetadata , $ key );
313
+ }
314
+ }
315
+
316
+ return $ this ->convertFilterArgsToTypes ($ args );
317
+ }
318
+
306
319
private function mergeFilterArgs (array $ args , array $ parsed , ResourceMetadata $ resourceMetadata = null , $ original = '' ): array
307
320
{
308
321
foreach ($ parsed as $ key => $ value ) {
@@ -367,9 +380,9 @@ private function convertFilterArgsToTypes(array $args): array
367
380
*
368
381
* @throws InvalidTypeException
369
382
*/
370
- private function convertType (Type $ type , bool $ input , ?string $ queryName , ?string $ mutationName , string $ resourceClass , ?string $ property , int $ depth )
383
+ private function convertType (Type $ type , bool $ input , ?string $ queryName , ?string $ mutationName , string $ resourceClass , string $ rootResource , ?string $ property , int $ depth )
371
384
{
372
- $ graphqlType = $ this ->typeConverter ->convertType ($ type , $ input , $ queryName , $ mutationName , $ resourceClass , $ property , $ depth );
385
+ $ graphqlType = $ this ->typeConverter ->convertType ($ type , $ input , $ queryName , $ mutationName , $ resourceClass , $ rootResource , $ property , $ depth );
373
386
374
387
if (null === $ graphqlType ) {
375
388
throw new InvalidTypeException (sprintf ('The type "%s" is not supported. ' , $ type ->getBuiltinType ()));
0 commit comments