From 4cd8de39445943dd2b718e52a3dfeee60934e209 Mon Sep 17 00:00:00 2001 From: Vladyslav Date: Tue, 7 May 2024 21:06:02 +0300 Subject: [PATCH] add value resolver --- DependencyInjection/StfalconApiExtension.php | 2 + Request/Filter/FilterExtractorInterface.php | 37 +++++++++++ Request/Filter/FilterInterface.php | 20 ++++++ Request/ValueResolver/FilterValueResolver.php | 64 +++++++++++++++++++ Resources/config/services.php | 3 +- .../StfalconApiExtensionTest.php | 5 +- 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 Request/Filter/FilterExtractorInterface.php create mode 100644 Request/Filter/FilterInterface.php create mode 100644 Request/ValueResolver/FilterValueResolver.php diff --git a/DependencyInjection/StfalconApiExtension.php b/DependencyInjection/StfalconApiExtension.php index add6521..a45a9b9 100644 --- a/DependencyInjection/StfalconApiExtension.php +++ b/DependencyInjection/StfalconApiExtension.php @@ -13,6 +13,7 @@ namespace StfalconStudio\ApiBundle\DependencyInjection; use Doctrine\ORM\EntityManagerInterface; +use StfalconStudio\ApiBundle\Request\Filter\FilterExtractorInterface; use StfalconStudio\ApiBundle\Security\JwtBlackListService; use StfalconStudio\ApiBundle\Service\Exception\ResponseProcessor\CustomAppExceptionResponseProcessorInterface; use Symfony\Component\Config\FileLocator; @@ -53,5 +54,6 @@ public function load(array $configs, ContainerBuilder $container): void $container->setParameter('stfalcon_api.api_host', $config['api_host']); $container->setParameter('stfalcon_api.json_schema_dir', $config['json_schema_dir']); $container->registerForAutoconfiguration(CustomAppExceptionResponseProcessorInterface::class)->addTag('stfalcon_api.exception_response_processor'); + $container->registerForAutoconfiguration(FilterExtractorInterface::class)->addTag('stfalcon_api.filter_extractor'); } } diff --git a/Request/Filter/FilterExtractorInterface.php b/Request/Filter/FilterExtractorInterface.php new file mode 100644 index 0000000..b09a75e --- /dev/null +++ b/Request/Filter/FilterExtractorInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Request\Filter; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * FilterExtractorInterface. + */ +interface FilterExtractorInterface +{ + /** + * @param Request $request + * + * @return FilterInterface + */ + public function extractFilterFromRequest(Request $request): FilterInterface; + + /** + * @param Request $request + * @param ArgumentMetadata $argument + * + * @return bool + */ + public function supports(Request $request, ArgumentMetadata $argument): bool; +} diff --git a/Request/Filter/FilterInterface.php b/Request/Filter/FilterInterface.php new file mode 100644 index 0000000..09aa0a0 --- /dev/null +++ b/Request/Filter/FilterInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Request\Filter; + +/** + * FilterInterface. + */ +interface FilterInterface +{ +} diff --git a/Request/ValueResolver/FilterValueResolver.php b/Request/ValueResolver/FilterValueResolver.php new file mode 100644 index 0000000..8441a19 --- /dev/null +++ b/Request/ValueResolver/FilterValueResolver.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace StfalconStudio\ApiBundle\Request\ValueResolver; + +use StfalconStudio\ApiBundle\Request\Filter\FilterExtractorInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * FilterValueResolver. + */ +class FilterValueResolver implements ValueResolverInterface +{ + /** + * @param iterable $filterExtractors + */ + public function __construct(private readonly iterable $filterExtractors) + { + } + + /** + * @param Request $request + * @param ArgumentMetadata $argument + * + * @return iterable + */ + public function resolve(Request $request, ArgumentMetadata $argument): iterable + { + $extractor = $this->getSupportedExtractor($request, $argument); + if (!$extractor instanceof FilterExtractorInterface) { + return []; + } + + yield $extractor->extractFilterFromRequest($request); + } + + /** + * @param Request $request + * @param ArgumentMetadata $argument + * + * @return ?FilterExtractorInterface + */ + private function getSupportedExtractor(Request $request, ArgumentMetadata $argument): ?FilterExtractorInterface + { + foreach ($this->filterExtractors as $extractor) { + if ($extractor->supports($request, $argument)) { + return $extractor; + } + } + + return null; + } +} diff --git a/Resources/config/services.php b/Resources/config/services.php index 1b48674..cd2e046 100644 --- a/Resources/config/services.php +++ b/Resources/config/services.php @@ -28,8 +28,9 @@ ->bind('$apiHost', '%stfalcon_api.api_host%') ->bind('$jsonSchemaDir', '%stfalcon_api.json_schema_dir%') ->bind('$environment', '%env(APP_ENV)%') - ->bind('iterable $errorResponseProcessors', new TaggedIteratorArgument('stfalcon_api.exception_response_processor')) ->bind('$symfonyConstraintViolationListNormalizer', new Reference('serializer.normalizer.constraint_violation_list')) + ->bind('iterable $errorResponseProcessors', new TaggedIteratorArgument('stfalcon_api.exception_response_processor')) + ->bind('iterable $filterExtractors', new TaggedIteratorArgument('stfalcon_api.filter_extractor')) ; $services->load('StfalconStudio\ApiBundle\\', __DIR__.'/../../{Asset,Request,Serializer,Service,Util,Validator}/'); diff --git a/Tests/DependencyInjection/StfalconApiExtensionTest.php b/Tests/DependencyInjection/StfalconApiExtensionTest.php index 3c84b92..d95b6cb 100644 --- a/Tests/DependencyInjection/StfalconApiExtensionTest.php +++ b/Tests/DependencyInjection/StfalconApiExtensionTest.php @@ -55,7 +55,10 @@ public function testLoadExtension(): void $childDefinitions = $this->container->getAutoconfiguredInstanceof(); foreach ($childDefinitions as $childDefinition) { - self::assertTrue($childDefinition->hasTag('stfalcon_api.exception_response_processor')); + self::assertTrue( + $childDefinition->hasTag('stfalcon_api.exception_response_processor') + || $childDefinition->hasTag('stfalcon_api.filter_extractor') + ); } }