164
164
use ApiPlatform \Metadata \ResourceClassResolverInterface ;
165
165
use ApiPlatform \Metadata \UrlGeneratorInterface ;
166
166
use ApiPlatform \Metadata \Util \Inflector ;
167
+ use ApiPlatform \Metadata \Util \ReflectionClassRecursiveIterator ;
167
168
use ApiPlatform \OpenApi \Factory \OpenApiFactory ;
168
169
use ApiPlatform \OpenApi \Factory \OpenApiFactoryInterface ;
169
170
use ApiPlatform \OpenApi \Options ;
@@ -426,25 +427,12 @@ public function register(): void
426
427
427
428
$ this ->app ->bind (OperationMetadataFactoryInterface::class, OperationMetadataFactory::class);
428
429
429
- $ this ->app ->tag ([
430
- BooleanFilter::class,
431
- EqualsFilter::class,
432
- PartialSearchFilter::class,
433
- DateFilter::class,
434
- OrderFilter::class,
435
- RangeFilter::class,
436
- SortFilter::class,
437
- SparseFieldset::class,
438
- ], EloquentFilterInterface::class);
439
-
440
430
$ this ->app ->bind (FilterQueryExtension::class, function (Application $ app ) {
441
431
$ tagged = iterator_to_array ($ app ->tagged (EloquentFilterInterface::class));
442
432
443
433
return new FilterQueryExtension (new ServiceLocator ($ tagged ));
444
434
});
445
435
446
- $ this ->app ->tag ([FilterQueryExtension::class], QueryExtensionInterface::class);
447
-
448
436
$ this ->app ->singleton (ItemProvider::class, function (Application $ app ) {
449
437
$ tagged = iterator_to_array ($ app ->tagged (LinksHandlerInterface::class));
450
438
@@ -455,7 +443,6 @@ public function register(): void
455
443
456
444
return new CollectionProvider ($ app ->make (Pagination::class), new LinksHandler ($ app , $ app ->make (ResourceMetadataCollectionFactoryInterface::class)), $ app ->tagged (QueryExtensionInterface::class), new ServiceLocator ($ tagged ));
457
445
});
458
- $ this ->app ->tag ([ItemProvider::class, CollectionProvider::class], ProviderInterface::class);
459
446
460
447
$ this ->app ->singleton (CallableProvider::class, function (Application $ app ) {
461
448
$ tagged = iterator_to_array ($ app ->tagged (ProviderInterface::class));
@@ -488,8 +475,6 @@ public function register(): void
488
475
});
489
476
}
490
477
491
- $ this ->app ->tag ([PropertyFilter::class], SerializerFilterInterface::class);
492
-
493
478
$ this ->app ->singleton (SerializerFilterParameterProvider::class, function (Application $ app ) {
494
479
$ tagged = iterator_to_array ($ app ->tagged (SerializerFilterInterface::class));
495
480
@@ -500,7 +485,6 @@ public function register(): void
500
485
$ this ->app ->singleton (SortFilterParameterProvider::class, function (Application $ app ) {
501
486
return new SortFilterParameterProvider ();
502
487
});
503
- $ this ->app ->tag ([SerializerFilterParameterProvider::class, SortFilterParameterProvider::class, SparseFieldsetParameterProvider::class], ParameterProviderInterface::class);
504
488
505
489
$ this ->app ->singleton ('filters ' , function (Application $ app ) {
506
490
return new ServiceLocator (array_merge (
@@ -540,7 +524,6 @@ public function register(): void
540
524
541
525
$ this ->app ->bind (ProviderInterface::class, ContentNegotiationProvider::class);
542
526
543
- $ this ->app ->tag ([RemoveProcessor::class, PersistProcessor::class], ProcessorInterface::class);
544
527
$ this ->app ->singleton (CallableProcessor::class, function (Application $ app ) {
545
528
/** @var ConfigRepository */
546
529
$ config = $ app ['config ' ];
@@ -953,7 +936,7 @@ public function register(): void
953
936
});
954
937
955
938
if (interface_exists (FieldsBuilderEnumInterface::class)) {
956
- $ this ->registerGraphQl ($ this -> app );
939
+ $ this ->registerGraphQl ();
957
940
}
958
941
959
942
$ this ->app ->singleton (JsonApiEntrypointNormalizer::class, function (Application $ app ) {
@@ -1119,9 +1102,11 @@ function (Application $app) {
1119
1102
Console \Maker \MakeStateProviderCommand::class,
1120
1103
]);
1121
1104
}
1105
+
1106
+ $ this ->tagServices ();
1122
1107
}
1123
1108
1124
- private function registerGraphQl (Application $ app ): void
1109
+ private function registerGraphQl (): void
1125
1110
{
1126
1111
$ this ->app ->singleton (GraphQlItemNormalizer::class, function (Application $ app ) {
1127
1112
return new GraphQlItemNormalizer (
@@ -1166,7 +1151,7 @@ private function registerGraphQl(Application $app): void
1166
1151
return new GraphQlHttpExceptionNormalizer ();
1167
1152
});
1168
1153
1169
- $ app ->singleton ('api_platform.graphql.type_locator ' , function (Application $ app ) {
1154
+ $ this -> app ->singleton ('api_platform.graphql.type_locator ' , function (Application $ app ) {
1170
1155
$ tagged = iterator_to_array ($ app ->tagged ('api_platform.graphql.type ' ));
1171
1156
$ services = [];
1172
1157
foreach ($ tagged as $ service ) {
@@ -1176,20 +1161,21 @@ private function registerGraphQl(Application $app): void
1176
1161
return new ServiceLocator ($ services );
1177
1162
});
1178
1163
1179
- $ app ->singleton (TypesFactoryInterface::class, function (Application $ app ) {
1164
+ $ this -> app ->singleton (TypesFactoryInterface::class, function (Application $ app ) {
1180
1165
$ tagged = iterator_to_array ($ app ->tagged ('api_platform.graphql.type ' ));
1181
1166
1182
1167
return new TypesFactory ($ app ->make ('api_platform.graphql.type_locator ' ), array_column ($ tagged , 'name ' ));
1183
1168
});
1184
- $ app ->singleton (TypesContainerInterface::class, function () {
1169
+
1170
+ $ this ->app ->singleton (TypesContainerInterface::class, function () {
1185
1171
return new TypesContainer ();
1186
1172
});
1187
1173
1188
- $ app ->singleton (ResourceFieldResolver::class, function (Application $ app ) {
1174
+ $ this -> app ->singleton (ResourceFieldResolver::class, function (Application $ app ) {
1189
1175
return new ResourceFieldResolver ($ app ->make (IriConverterInterface::class));
1190
1176
});
1191
1177
1192
- $ app ->singleton (ContextAwareTypeBuilderInterface::class, function (Application $ app ) {
1178
+ $ this -> app ->singleton (ContextAwareTypeBuilderInterface::class, function (Application $ app ) {
1193
1179
return new TypeBuilder (
1194
1180
$ app ->make (TypesContainerInterface::class),
1195
1181
$ app ->make (ResourceFieldResolver::class),
@@ -1198,7 +1184,7 @@ private function registerGraphQl(Application $app): void
1198
1184
);
1199
1185
});
1200
1186
1201
- $ app ->singleton (TypeConverterInterface::class, function (Application $ app ) {
1187
+ $ this -> app ->singleton (TypeConverterInterface::class, function (Application $ app ) {
1202
1188
return new TypeConverter (
1203
1189
$ app ->make (ContextAwareTypeBuilderInterface::class),
1204
1190
$ app ->make (TypesContainerInterface::class),
@@ -1207,11 +1193,11 @@ private function registerGraphQl(Application $app): void
1207
1193
);
1208
1194
});
1209
1195
1210
- $ app ->singleton (GraphQlSerializerContextBuilder::class, function (Application $ app ) {
1196
+ $ this -> app ->singleton (GraphQlSerializerContextBuilder::class, function (Application $ app ) {
1211
1197
return new GraphQlSerializerContextBuilder ($ app ->make (NameConverterInterface::class));
1212
1198
});
1213
1199
1214
- $ app ->singleton (GraphQlReadProvider::class, function (Application $ app ) {
1200
+ $ this -> app ->singleton (GraphQlReadProvider::class, function (Application $ app ) {
1215
1201
/** @var ConfigRepository */
1216
1202
$ config = $ app ['config ' ];
1217
1203
@@ -1222,9 +1208,9 @@ private function registerGraphQl(Application $app): void
1222
1208
$ config ->get ('api-platform.graphql.nesting_separator ' ) ?? '__ '
1223
1209
);
1224
1210
});
1225
- $ app ->alias (GraphQlReadProvider::class, 'api_platform.graphql.state_provider.read ' );
1211
+ $ this -> app ->alias (GraphQlReadProvider::class, 'api_platform.graphql.state_provider.read ' );
1226
1212
1227
- $ app ->singleton (ErrorProvider::class, function (Application $ app ) {
1213
+ $ this -> app ->singleton (ErrorProvider::class, function (Application $ app ) {
1228
1214
/** @var ConfigRepository */
1229
1215
$ config = $ app ['config ' ];
1230
1216
@@ -1234,9 +1220,8 @@ private function registerGraphQl(Application $app): void
1234
1220
$ app ->make (ResourceMetadataCollectionFactoryInterface::class),
1235
1221
);
1236
1222
});
1237
- $ app ->tag ([ErrorProvider::class], ProviderInterface::class);
1238
1223
1239
- $ app ->singleton (ResolverProvider::class, function (Application $ app ) {
1224
+ $ this -> app ->singleton (ResolverProvider::class, function (Application $ app ) {
1240
1225
$ resolvers = iterator_to_array ($ app ->tagged ('api_platform.graphql.resolver ' ));
1241
1226
$ taggedItemResolvers = iterator_to_array ($ app ->tagged (QueryItemResolverInterface::class));
1242
1227
$ taggedCollectionResolvers = iterator_to_array ($ app ->tagged (QueryCollectionResolverInterface::class));
@@ -1247,19 +1232,19 @@ private function registerGraphQl(Application $app): void
1247
1232
);
1248
1233
});
1249
1234
1250
- $ app ->alias (ResolverProvider::class, 'api_platform.graphql.state_provider.resolver ' );
1235
+ $ this -> app ->alias (ResolverProvider::class, 'api_platform.graphql.state_provider.resolver ' );
1251
1236
1252
- $ app ->singleton (GraphQlDenormalizeProvider::class, function (Application $ app ) {
1237
+ $ this -> app ->singleton (GraphQlDenormalizeProvider::class, function (Application $ app ) {
1253
1238
return new GraphQlDenormalizeProvider (
1254
1239
$ this ->app ->make (ResolverProvider::class),
1255
1240
$ app ->make (SerializerInterface::class),
1256
1241
$ app ->make (GraphQlSerializerContextBuilder::class)
1257
1242
);
1258
1243
});
1259
1244
1260
- $ app ->alias (GraphQlDenormalizeProvider::class, 'api_platform.graphql.state_provider.denormalize ' );
1245
+ $ this -> app ->alias (GraphQlDenormalizeProvider::class, 'api_platform.graphql.state_provider.denormalize ' );
1261
1246
1262
- $ app ->singleton ('api_platform.graphql.state_provider.parameter ' , function (Application $ app ) {
1247
+ $ this -> app ->singleton ('api_platform.graphql.state_provider.parameter ' , function (Application $ app ) {
1263
1248
$ tagged = iterator_to_array ($ app ->tagged (ParameterProviderInterface::class));
1264
1249
$ tagged ['api_platform.serializer.filter_parameter_provider ' ] = $ app ->make (SerializerFilterParameterProvider::class);
1265
1250
@@ -1274,34 +1259,34 @@ private function registerGraphQl(Application $app): void
1274
1259
);
1275
1260
});
1276
1261
1277
- $ app ->singleton ('api_platform.graphql.state_provider.access_checker ' , function (Application $ app ) {
1262
+ $ this -> app ->singleton ('api_platform.graphql.state_provider.access_checker ' , function (Application $ app ) {
1278
1263
return new AccessCheckerProvider ($ app ->make ('api_platform.graphql.state_provider.parameter ' ), $ app ->make (ResourceAccessCheckerInterface::class));
1279
1264
});
1280
1265
1281
- $ app ->singleton (NormalizeProcessor::class, function (Application $ app ) {
1266
+ $ this -> app ->singleton (NormalizeProcessor::class, function (Application $ app ) {
1282
1267
return new NormalizeProcessor (
1283
1268
$ app ->make (SerializerInterface::class),
1284
1269
$ app ->make (GraphQlSerializerContextBuilder::class),
1285
1270
$ app ->make (Pagination::class)
1286
1271
);
1287
1272
});
1288
- $ app ->alias (NormalizeProcessor::class, 'api_platform.graphql.state_processor.normalize ' );
1273
+ $ this -> app ->alias (NormalizeProcessor::class, 'api_platform.graphql.state_processor.normalize ' );
1289
1274
1290
- $ app ->singleton ('api_platform.graphql.state_processor ' , function (Application $ app ) {
1275
+ $ this -> app ->singleton ('api_platform.graphql.state_processor ' , function (Application $ app ) {
1291
1276
return new WriteProcessor (
1292
1277
$ app ->make ('api_platform.graphql.state_processor.normalize ' ),
1293
1278
$ app ->make (CallableProcessor::class),
1294
1279
);
1295
1280
});
1296
1281
1297
- $ app ->singleton (ResolverFactoryInterface::class, function (Application $ app ) {
1282
+ $ this -> app ->singleton (ResolverFactoryInterface::class, function (Application $ app ) {
1298
1283
return new ResolverFactory (
1299
1284
$ app ->make ('api_platform.graphql.state_provider.access_checker ' ),
1300
1285
$ app ->make ('api_platform.graphql.state_processor ' )
1301
1286
);
1302
1287
});
1303
1288
1304
- $ app ->singleton (FieldsBuilderEnumInterface::class, function (Application $ app ) {
1289
+ $ this -> app ->singleton (FieldsBuilderEnumInterface::class, function (Application $ app ) {
1305
1290
/** @var ConfigRepository */
1306
1291
$ config = $ app ['config ' ];
1307
1292
@@ -1322,30 +1307,30 @@ private function registerGraphQl(Application $app): void
1322
1307
);
1323
1308
});
1324
1309
1325
- $ app ->singleton (SchemaBuilderInterface::class, function (Application $ app ) {
1310
+ $ this -> app ->singleton (SchemaBuilderInterface::class, function (Application $ app ) {
1326
1311
return new SchemaBuilder ($ app ->make (ResourceNameCollectionFactoryInterface::class), $ app ->make (ResourceMetadataCollectionFactoryInterface::class), $ app ->make (TypesFactoryInterface::class), $ app ->make (TypesContainerInterface::class), $ app ->make (FieldsBuilderEnumInterface::class));
1327
1312
});
1328
1313
1329
- $ app ->singleton (ErrorHandlerInterface::class, function () {
1314
+ $ this -> app ->singleton (ErrorHandlerInterface::class, function () {
1330
1315
return new GraphQlErrorHandler ();
1331
1316
});
1332
1317
1333
- $ app ->singleton (ExecutorInterface::class, function (Application $ app ) {
1318
+ $ this -> app ->singleton (ExecutorInterface::class, function (Application $ app ) {
1334
1319
/** @var ConfigRepository */
1335
1320
$ config = $ app ['config ' ];
1336
1321
1337
1322
return new Executor ($ config ->get ('api-platform.graphql.introspection.enabled ' ) ?? false , $ config ->get ('api-platform.graphql.max_query_complexity ' ) ?? 500 , $ config ->get ('api-platform.graphql.max_query_depth ' ) ?? 200 );
1338
1323
});
1339
1324
1340
- $ app ->singleton (GraphiQlController::class, function (Application $ app ) {
1325
+ $ this -> app ->singleton (GraphiQlController::class, function (Application $ app ) {
1341
1326
/** @var ConfigRepository */
1342
1327
$ config = $ app ['config ' ];
1343
1328
$ prefix = $ config ->get ('api-platform.defaults.route_prefix ' ) ?? '' ;
1344
1329
1345
1330
return new GraphiQlController ($ prefix );
1346
1331
});
1347
1332
1348
- $ app ->singleton (GraphQlEntrypointController::class, function (Application $ app ) {
1333
+ $ this -> app ->singleton (GraphQlEntrypointController::class, function (Application $ app ) {
1349
1334
/** @var ConfigRepository */
1350
1335
$ config = $ app ['config ' ];
1351
1336
@@ -1389,4 +1374,54 @@ public function boot(): void
1389
1374
1390
1375
$ this ->loadRoutesFrom (__DIR__ .'/routes/api.php ' );
1391
1376
}
1377
+
1378
+ private function tagServices (): void
1379
+ {
1380
+ $ directory = app_path ();
1381
+ $ classes = ReflectionClassRecursiveIterator::getReflectionClassesFromDirectories ([$ directory ]);
1382
+
1383
+ $ this ->app ->tag ([FilterQueryExtension::class], QueryExtensionInterface::class);
1384
+ $ this ->autoconfigure ($ classes , QueryExtensionInterface::class);
1385
+
1386
+ $ this ->app ->tag ([PropertyFilter::class], SerializerFilterInterface::class);
1387
+ $ this ->autoconfigure ($ classes , SerializerFilterInterface::class);
1388
+
1389
+ $ this ->app ->tag ([SerializerFilterParameterProvider::class, SortFilterParameterProvider::class, SparseFieldsetParameterProvider::class], ParameterProviderInterface::class);
1390
+ $ this ->autoconfigure ($ classes , ParameterProviderInterface::class);
1391
+
1392
+ $ this ->app ->tag ([
1393
+ BooleanFilter::class,
1394
+ EqualsFilter::class,
1395
+ PartialSearchFilter::class,
1396
+ DateFilter::class,
1397
+ OrderFilter::class,
1398
+ RangeFilter::class,
1399
+ SortFilter::class,
1400
+ SparseFieldset::class,
1401
+ ], EloquentFilterInterface::class);
1402
+ $ this ->autoconfigure ($ classes , EloquentFilterInterface::class);
1403
+
1404
+ $ this ->app ->tag ([ItemProvider::class, CollectionProvider::class, ErrorProvider::class], ProviderInterface::class);
1405
+ $ this ->autoconfigure ($ classes , ProviderInterface::class);
1406
+ $ this ->app ->tag ([RemoveProcessor::class, PersistProcessor::class], ProcessorInterface::class);
1407
+ $ this ->autoconfigure ($ classes , ProcessorInterface::class);
1408
+ }
1409
+
1410
+ /**
1411
+ * @param array<class-string, \ReflectionClass> $classes
1412
+ * @param class-string $interface
1413
+ */
1414
+ private function autoconfigure (array $ classes , string $ interface ): void
1415
+ {
1416
+ $ m = [];
1417
+ foreach ($ classes as $ className => $ refl ) {
1418
+ if ($ refl ->implementsInterface ($ interface )) {
1419
+ $ m [] = $ className ;
1420
+ }
1421
+ }
1422
+
1423
+ if ($ m ) {
1424
+ $ this ->app ->tag ($ m , $ interface );
1425
+ }
1426
+ }
1392
1427
}
0 commit comments