diff --git a/src/DependencyInjection/CompilerPass/SchemaProcessorCompilerPass.php b/src/DependencyInjection/CompilerPass/SchemaProcessorCompilerPass.php new file mode 100644 index 0000000..8ecb456 --- /dev/null +++ b/src/DependencyInjection/CompilerPass/SchemaProcessorCompilerPass.php @@ -0,0 +1,38 @@ +hasParameter(self::FEATURE_ENABLED_PARAMETER) + || $container->getParameter(self::FEATURE_ENABLED_PARAMETER) === false + ) { + return; + } + + $container + ->setDefinition( + OpenApiFactory::class, + new Definition(OpenApiFactory::class), + ) + ->setArguments([ + new Reference('api_platform.openapi.factory.inner'), + new TaggedIteratorArgument('netgen_api_platform_extras.open_api_processor'), + ]) + ->setDecoratedService('api_platform.openapi.factory', 'api_platform.openapi.factory.inner', -25); + } +} diff --git a/src/NetgenApiPlatformExtrasBundle.php b/src/NetgenApiPlatformExtrasBundle.php index a17ae90..f73e626 100644 --- a/src/NetgenApiPlatformExtrasBundle.php +++ b/src/NetgenApiPlatformExtrasBundle.php @@ -5,6 +5,8 @@ namespace Netgen\ApiPlatformExtras; use Netgen\ApiPlatformExtras\DependencyInjection\CompilerPass\IriTemplateGeneratorCompilerPass; +use Netgen\ApiPlatformExtras\DependencyInjection\CompilerPass\SchemaProcessorCompilerPass; +use Netgen\ApiPlatformExtras\OpenApi\Processor\OpenApiProcessorInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -12,8 +14,15 @@ final class NetgenApiPlatformExtrasBundle extends Bundle { public function build(ContainerBuilder $container): void { - $container->addCompilerPass( + $container + ->addCompilerPass( new IriTemplateGeneratorCompilerPass(), + ) + ->addCompilerPass( + new SchemaProcessorCompilerPass(), ); + + $container->registerForAutoconfiguration(OpenApiProcessorInterface::class) + ->addTag('netgen_api_platform_extras.open_api_processor'); } } diff --git a/src/OpenApi/Factory/OpenApiFactory.php b/src/OpenApi/Factory/OpenApiFactory.php new file mode 100644 index 0000000..4583788 --- /dev/null +++ b/src/OpenApi/Factory/OpenApiFactory.php @@ -0,0 +1,57 @@ + $processors + */ + public function __construct( + private OpenApiFactoryInterface $decorated, + private iterable $processors, + ) { + $this->processors = $this->sortProcessors($processors); + } + + public function __invoke(array $context = []): OpenApi + { + $openApi = ($this->decorated)($context); + + return $this->applyProcessors($openApi); + } + + private function applyProcessors(OpenApi $openApi): OpenApi + { + foreach ($this->processors as $processor) { + $openApi = $processor->process($openApi); + } + + return $openApi; + } + + /** + * @param iterable<\Netgen\ApiPlatformExtras\OpenApi\Processor\OpenApiProcessorInterface> $processors + * + * @return \Netgen\ApiPlatformExtras\OpenApi\Processor\OpenApiProcessorInterface[] + */ + private function sortProcessors(iterable $processors): array + { + $processors = iterator_to_array($processors); + + usort( + $processors, + static fn ($a, $b): int => $b::getPriority() <=> $a::getPriority(), + ); + + return $processors; + } +} diff --git a/src/OpenApi/Processor/OpenApiProcessorInterface.php b/src/OpenApi/Processor/OpenApiProcessorInterface.php new file mode 100644 index 0000000..5849bfd --- /dev/null +++ b/src/OpenApi/Processor/OpenApiProcessorInterface.php @@ -0,0 +1,21 @@ +