164164use ApiPlatform \Metadata \ResourceClassResolverInterface ;
165165use ApiPlatform \Metadata \UrlGeneratorInterface ;
166166use ApiPlatform \Metadata \Util \Inflector ;
167+ use ApiPlatform \Metadata \Util \ReflectionClassRecursiveIterator ;
167168use ApiPlatform \OpenApi \Factory \OpenApiFactory ;
168169use ApiPlatform \OpenApi \Factory \OpenApiFactoryInterface ;
169170use ApiPlatform \OpenApi \Options ;
@@ -426,25 +427,12 @@ public function register(): void
426427
427428 $ this ->app ->bind (OperationMetadataFactoryInterface::class, OperationMetadataFactory::class);
428429
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-
440430 $ this ->app ->bind (FilterQueryExtension::class, function (Application $ app ) {
441431 $ tagged = iterator_to_array ($ app ->tagged (EloquentFilterInterface::class));
442432
443433 return new FilterQueryExtension (new ServiceLocator ($ tagged ));
444434 });
445435
446- $ this ->app ->tag ([FilterQueryExtension::class], QueryExtensionInterface::class);
447-
448436 $ this ->app ->singleton (ItemProvider::class, function (Application $ app ) {
449437 $ tagged = iterator_to_array ($ app ->tagged (LinksHandlerInterface::class));
450438
@@ -455,7 +443,6 @@ public function register(): void
455443
456444 return new CollectionProvider ($ app ->make (Pagination::class), new LinksHandler ($ app , $ app ->make (ResourceMetadataCollectionFactoryInterface::class)), $ app ->tagged (QueryExtensionInterface::class), new ServiceLocator ($ tagged ));
457445 });
458- $ this ->app ->tag ([ItemProvider::class, CollectionProvider::class], ProviderInterface::class);
459446
460447 $ this ->app ->singleton (CallableProvider::class, function (Application $ app ) {
461448 $ tagged = iterator_to_array ($ app ->tagged (ProviderInterface::class));
@@ -488,8 +475,6 @@ public function register(): void
488475 });
489476 }
490477
491- $ this ->app ->tag ([PropertyFilter::class], SerializerFilterInterface::class);
492-
493478 $ this ->app ->singleton (SerializerFilterParameterProvider::class, function (Application $ app ) {
494479 $ tagged = iterator_to_array ($ app ->tagged (SerializerFilterInterface::class));
495480
@@ -500,7 +485,6 @@ public function register(): void
500485 $ this ->app ->singleton (SortFilterParameterProvider::class, function (Application $ app ) {
501486 return new SortFilterParameterProvider ();
502487 });
503- $ this ->app ->tag ([SerializerFilterParameterProvider::class, SortFilterParameterProvider::class, SparseFieldsetParameterProvider::class], ParameterProviderInterface::class);
504488
505489 $ this ->app ->singleton ('filters ' , function (Application $ app ) {
506490 return new ServiceLocator (array_merge (
@@ -540,7 +524,6 @@ public function register(): void
540524
541525 $ this ->app ->bind (ProviderInterface::class, ContentNegotiationProvider::class);
542526
543- $ this ->app ->tag ([RemoveProcessor::class, PersistProcessor::class], ProcessorInterface::class);
544527 $ this ->app ->singleton (CallableProcessor::class, function (Application $ app ) {
545528 /** @var ConfigRepository */
546529 $ config = $ app ['config ' ];
@@ -953,7 +936,7 @@ public function register(): void
953936 });
954937
955938 if (interface_exists (FieldsBuilderEnumInterface::class)) {
956- $ this ->registerGraphQl ($ this -> app );
939+ $ this ->registerGraphQl ();
957940 }
958941
959942 $ this ->app ->singleton (JsonApiEntrypointNormalizer::class, function (Application $ app ) {
@@ -1119,9 +1102,11 @@ function (Application $app) {
11191102 Console \Maker \MakeStateProviderCommand::class,
11201103 ]);
11211104 }
1105+
1106+ $ this ->tagServices ();
11221107 }
11231108
1124- private function registerGraphQl (Application $ app ): void
1109+ private function registerGraphQl (): void
11251110 {
11261111 $ this ->app ->singleton (GraphQlItemNormalizer::class, function (Application $ app ) {
11271112 return new GraphQlItemNormalizer (
@@ -1166,7 +1151,7 @@ private function registerGraphQl(Application $app): void
11661151 return new GraphQlHttpExceptionNormalizer ();
11671152 });
11681153
1169- $ app ->singleton ('api_platform.graphql.type_locator ' , function (Application $ app ) {
1154+ $ this -> app ->singleton ('api_platform.graphql.type_locator ' , function (Application $ app ) {
11701155 $ tagged = iterator_to_array ($ app ->tagged ('api_platform.graphql.type ' ));
11711156 $ services = [];
11721157 foreach ($ tagged as $ service ) {
@@ -1176,20 +1161,21 @@ private function registerGraphQl(Application $app): void
11761161 return new ServiceLocator ($ services );
11771162 });
11781163
1179- $ app ->singleton (TypesFactoryInterface::class, function (Application $ app ) {
1164+ $ this -> app ->singleton (TypesFactoryInterface::class, function (Application $ app ) {
11801165 $ tagged = iterator_to_array ($ app ->tagged ('api_platform.graphql.type ' ));
11811166
11821167 return new TypesFactory ($ app ->make ('api_platform.graphql.type_locator ' ), array_column ($ tagged , 'name ' ));
11831168 });
1184- $ app ->singleton (TypesContainerInterface::class, function () {
1169+
1170+ $ this ->app ->singleton (TypesContainerInterface::class, function () {
11851171 return new TypesContainer ();
11861172 });
11871173
1188- $ app ->singleton (ResourceFieldResolver::class, function (Application $ app ) {
1174+ $ this -> app ->singleton (ResourceFieldResolver::class, function (Application $ app ) {
11891175 return new ResourceFieldResolver ($ app ->make (IriConverterInterface::class));
11901176 });
11911177
1192- $ app ->singleton (ContextAwareTypeBuilderInterface::class, function (Application $ app ) {
1178+ $ this -> app ->singleton (ContextAwareTypeBuilderInterface::class, function (Application $ app ) {
11931179 return new TypeBuilder (
11941180 $ app ->make (TypesContainerInterface::class),
11951181 $ app ->make (ResourceFieldResolver::class),
@@ -1198,7 +1184,7 @@ private function registerGraphQl(Application $app): void
11981184 );
11991185 });
12001186
1201- $ app ->singleton (TypeConverterInterface::class, function (Application $ app ) {
1187+ $ this -> app ->singleton (TypeConverterInterface::class, function (Application $ app ) {
12021188 return new TypeConverter (
12031189 $ app ->make (ContextAwareTypeBuilderInterface::class),
12041190 $ app ->make (TypesContainerInterface::class),
@@ -1207,11 +1193,11 @@ private function registerGraphQl(Application $app): void
12071193 );
12081194 });
12091195
1210- $ app ->singleton (GraphQlSerializerContextBuilder::class, function (Application $ app ) {
1196+ $ this -> app ->singleton (GraphQlSerializerContextBuilder::class, function (Application $ app ) {
12111197 return new GraphQlSerializerContextBuilder ($ app ->make (NameConverterInterface::class));
12121198 });
12131199
1214- $ app ->singleton (GraphQlReadProvider::class, function (Application $ app ) {
1200+ $ this -> app ->singleton (GraphQlReadProvider::class, function (Application $ app ) {
12151201 /** @var ConfigRepository */
12161202 $ config = $ app ['config ' ];
12171203
@@ -1222,9 +1208,9 @@ private function registerGraphQl(Application $app): void
12221208 $ config ->get ('api-platform.graphql.nesting_separator ' ) ?? '__ '
12231209 );
12241210 });
1225- $ app ->alias (GraphQlReadProvider::class, 'api_platform.graphql.state_provider.read ' );
1211+ $ this -> app ->alias (GraphQlReadProvider::class, 'api_platform.graphql.state_provider.read ' );
12261212
1227- $ app ->singleton (ErrorProvider::class, function (Application $ app ) {
1213+ $ this -> app ->singleton (ErrorProvider::class, function (Application $ app ) {
12281214 /** @var ConfigRepository */
12291215 $ config = $ app ['config ' ];
12301216
@@ -1234,9 +1220,8 @@ private function registerGraphQl(Application $app): void
12341220 $ app ->make (ResourceMetadataCollectionFactoryInterface::class),
12351221 );
12361222 });
1237- $ app ->tag ([ErrorProvider::class], ProviderInterface::class);
12381223
1239- $ app ->singleton (ResolverProvider::class, function (Application $ app ) {
1224+ $ this -> app ->singleton (ResolverProvider::class, function (Application $ app ) {
12401225 $ resolvers = iterator_to_array ($ app ->tagged ('api_platform.graphql.resolver ' ));
12411226 $ taggedItemResolvers = iterator_to_array ($ app ->tagged (QueryItemResolverInterface::class));
12421227 $ taggedCollectionResolvers = iterator_to_array ($ app ->tagged (QueryCollectionResolverInterface::class));
@@ -1247,19 +1232,19 @@ private function registerGraphQl(Application $app): void
12471232 );
12481233 });
12491234
1250- $ app ->alias (ResolverProvider::class, 'api_platform.graphql.state_provider.resolver ' );
1235+ $ this -> app ->alias (ResolverProvider::class, 'api_platform.graphql.state_provider.resolver ' );
12511236
1252- $ app ->singleton (GraphQlDenormalizeProvider::class, function (Application $ app ) {
1237+ $ this -> app ->singleton (GraphQlDenormalizeProvider::class, function (Application $ app ) {
12531238 return new GraphQlDenormalizeProvider (
12541239 $ this ->app ->make (ResolverProvider::class),
12551240 $ app ->make (SerializerInterface::class),
12561241 $ app ->make (GraphQlSerializerContextBuilder::class)
12571242 );
12581243 });
12591244
1260- $ app ->alias (GraphQlDenormalizeProvider::class, 'api_platform.graphql.state_provider.denormalize ' );
1245+ $ this -> app ->alias (GraphQlDenormalizeProvider::class, 'api_platform.graphql.state_provider.denormalize ' );
12611246
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 ) {
12631248 $ tagged = iterator_to_array ($ app ->tagged (ParameterProviderInterface::class));
12641249 $ tagged ['api_platform.serializer.filter_parameter_provider ' ] = $ app ->make (SerializerFilterParameterProvider::class);
12651250
@@ -1274,34 +1259,34 @@ private function registerGraphQl(Application $app): void
12741259 );
12751260 });
12761261
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 ) {
12781263 return new AccessCheckerProvider ($ app ->make ('api_platform.graphql.state_provider.parameter ' ), $ app ->make (ResourceAccessCheckerInterface::class));
12791264 });
12801265
1281- $ app ->singleton (NormalizeProcessor::class, function (Application $ app ) {
1266+ $ this -> app ->singleton (NormalizeProcessor::class, function (Application $ app ) {
12821267 return new NormalizeProcessor (
12831268 $ app ->make (SerializerInterface::class),
12841269 $ app ->make (GraphQlSerializerContextBuilder::class),
12851270 $ app ->make (Pagination::class)
12861271 );
12871272 });
1288- $ app ->alias (NormalizeProcessor::class, 'api_platform.graphql.state_processor.normalize ' );
1273+ $ this -> app ->alias (NormalizeProcessor::class, 'api_platform.graphql.state_processor.normalize ' );
12891274
1290- $ app ->singleton ('api_platform.graphql.state_processor ' , function (Application $ app ) {
1275+ $ this -> app ->singleton ('api_platform.graphql.state_processor ' , function (Application $ app ) {
12911276 return new WriteProcessor (
12921277 $ app ->make ('api_platform.graphql.state_processor.normalize ' ),
12931278 $ app ->make (CallableProcessor::class),
12941279 );
12951280 });
12961281
1297- $ app ->singleton (ResolverFactoryInterface::class, function (Application $ app ) {
1282+ $ this -> app ->singleton (ResolverFactoryInterface::class, function (Application $ app ) {
12981283 return new ResolverFactory (
12991284 $ app ->make ('api_platform.graphql.state_provider.access_checker ' ),
13001285 $ app ->make ('api_platform.graphql.state_processor ' )
13011286 );
13021287 });
13031288
1304- $ app ->singleton (FieldsBuilderEnumInterface::class, function (Application $ app ) {
1289+ $ this -> app ->singleton (FieldsBuilderEnumInterface::class, function (Application $ app ) {
13051290 /** @var ConfigRepository */
13061291 $ config = $ app ['config ' ];
13071292
@@ -1322,30 +1307,30 @@ private function registerGraphQl(Application $app): void
13221307 );
13231308 });
13241309
1325- $ app ->singleton (SchemaBuilderInterface::class, function (Application $ app ) {
1310+ $ this -> app ->singleton (SchemaBuilderInterface::class, function (Application $ app ) {
13261311 return new SchemaBuilder ($ app ->make (ResourceNameCollectionFactoryInterface::class), $ app ->make (ResourceMetadataCollectionFactoryInterface::class), $ app ->make (TypesFactoryInterface::class), $ app ->make (TypesContainerInterface::class), $ app ->make (FieldsBuilderEnumInterface::class));
13271312 });
13281313
1329- $ app ->singleton (ErrorHandlerInterface::class, function () {
1314+ $ this -> app ->singleton (ErrorHandlerInterface::class, function () {
13301315 return new GraphQlErrorHandler ();
13311316 });
13321317
1333- $ app ->singleton (ExecutorInterface::class, function (Application $ app ) {
1318+ $ this -> app ->singleton (ExecutorInterface::class, function (Application $ app ) {
13341319 /** @var ConfigRepository */
13351320 $ config = $ app ['config ' ];
13361321
13371322 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 );
13381323 });
13391324
1340- $ app ->singleton (GraphiQlController::class, function (Application $ app ) {
1325+ $ this -> app ->singleton (GraphiQlController::class, function (Application $ app ) {
13411326 /** @var ConfigRepository */
13421327 $ config = $ app ['config ' ];
13431328 $ prefix = $ config ->get ('api-platform.defaults.route_prefix ' ) ?? '' ;
13441329
13451330 return new GraphiQlController ($ prefix );
13461331 });
13471332
1348- $ app ->singleton (GraphQlEntrypointController::class, function (Application $ app ) {
1333+ $ this -> app ->singleton (GraphQlEntrypointController::class, function (Application $ app ) {
13491334 /** @var ConfigRepository */
13501335 $ config = $ app ['config ' ];
13511336
@@ -1389,4 +1374,54 @@ public function boot(): void
13891374
13901375 $ this ->loadRoutesFrom (__DIR__ .'/routes/api.php ' );
13911376 }
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+ }
13921427}
0 commit comments