diff --git a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php index 656d82ca21..fa09b54012 100644 --- a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php +++ b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php @@ -53,6 +53,7 @@ public function __construct( private readonly ?ContainerInterface $filterLocator = null, private readonly ?NameConverterInterface $nameConverter = null, private readonly ?LoggerInterface $logger = null, + private readonly bool $withLegacyFilterMetadata = true, ) { } @@ -269,7 +270,7 @@ private function setDefaults(string $key, Parameter $parameter, ?object $filter, $parameter = $this->addFilterMetadata($parameter); - if ($filter instanceof FilterInterface) { + if ($filter instanceof FilterInterface && $this->withLegacyFilterMetadata) { try { return $this->getLegacyFilterMetadata($parameter, $operation, $filter); } catch (RuntimeException $exception) { diff --git a/src/Metadata/Tests/Resource/Factory/ParameterResourceMetadataCollectionFactoryTest.php b/src/Metadata/Tests/Resource/Factory/ParameterResourceMetadataCollectionFactoryTest.php index 615dc1ce8f..2e8a082ea0 100644 --- a/src/Metadata/Tests/Resource/Factory/ParameterResourceMetadataCollectionFactoryTest.php +++ b/src/Metadata/Tests/Resource/Factory/ParameterResourceMetadataCollectionFactoryTest.php @@ -17,6 +17,7 @@ use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\FilterInterface; use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\JsonSchemaFilterInterface; use ApiPlatform\Metadata\Parameters; use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; @@ -83,6 +84,65 @@ public function getDescription(string $resourceClass): array $this->assertNull($everywhere->getOpenApi()); } + public function testParameterFactoryWithoutLegacyDescription(): void + { + $nameCollection = $this->createStub(PropertyNameCollectionFactoryInterface::class); + $nameCollection->method('create')->willReturn(new PropertyNameCollection(['id', 'hydra', 'everywhere'])); + $propertyMetadata = $this->createStub(PropertyMetadataFactoryInterface::class); + $propertyMetadata->method('create')->willReturnOnConsecutiveCalls( + new ApiProperty(identifier: true), + new ApiProperty(readable: true), + new ApiProperty(readable: true), + new ApiProperty(identifier: true), + new ApiProperty(readable: true), + new ApiProperty(readable: true) + ); + $filterLocator = $this->createStub(ContainerInterface::class); + $filterLocator->method('has')->willReturn(true); + $filterLocator->method('get')->willReturn(new class implements FilterInterface, JsonSchemaFilterInterface { + public function getDescription(string $resourceClass): array + { + // @phpstan-ignore-next-line return.type + return [ + 'hydra' => [ + 'property' => 'hydra', + 'type' => 'string', + 'required' => false, + 'schema' => ['type' => 'foo'], + 'openapi' => new Parameter('test', 'query'), + ], + 'everywhere' => [ + 'property' => 'everywhere', + 'type' => 'string', + 'required' => false, + 'openapi' => ['allowEmptyValue' => true], + ], + ]; + } + + public function getSchema(\ApiPlatform\Metadata\Parameter $parameter): array + { + return ['type' => 'string']; + } + }); + $parameter = new ParameterResourceMetadataCollectionFactory( + $nameCollection, + $propertyMetadata, + new AttributesResourceMetadataCollectionFactory(), + $filterLocator, + null, + null, + false, + ); + $operation = $parameter->create(WithParameter::class)->getOperation('collection'); + $this->assertInstanceOf(Parameters::class, $parameters = $operation->getParameters()); + $hydraParameter = $parameters->get('hydra', QueryParameter::class); + $this->assertSame(['type' => 'string'], $hydraParameter->getSchema()); + $this->assertNull($hydraParameter->getOpenApi()); + $everywhere = $parameters->get('everywhere', QueryParameter::class); + $this->assertNull($everywhere->getOpenApi()); + } + public function testQueryParameterWithPropertyPlaceholder(): void { $nameCollection = $this->createStub(PropertyNameCollectionFactoryInterface::class); diff --git a/src/Symfony/Bundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DependencyInjection/Configuration.php index 354b7b1f2d..adc7a851c0 100644 --- a/src/Symfony/Bundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DependencyInjection/Configuration.php @@ -85,6 +85,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->booleanNode('show_webby')->defaultTrue()->info('If true, show Webby on the documentation page')->end() ->booleanNode('use_symfony_listeners')->defaultFalse()->info(sprintf('Uses Symfony event listeners instead of the %s.', MainController::class))->end() + ->booleanNode('legacy_filter_metadata')->defaultTrue()->info('Read the deprecated `getDescription` method to generate filters metadata.')->end() ->scalarNode('name_converter')->defaultNull()->info('Specify a name converter to use.')->end() ->scalarNode('asset_package')->defaultNull()->info('Specify an asset package name to use.')->end() ->scalarNode('path_segment_name_generator')->defaultValue('api_platform.metadata.path_segment_name_generator.underscore')->info('Specify a path name generator to use.')->end() diff --git a/src/Symfony/Bundle/Resources/config/metadata/resource.php b/src/Symfony/Bundle/Resources/config/metadata/resource.php index 0e0b3c088d..8b4c2d4929 100644 --- a/src/Symfony/Bundle/Resources/config/metadata/resource.php +++ b/src/Symfony/Bundle/Resources/config/metadata/resource.php @@ -151,6 +151,7 @@ service('api_platform.filter_locator')->ignoreOnInvalid(), service('api_platform.name_converter')->ignoreOnInvalid(), service('logger')->ignoreOnInvalid(), + '%api_platform.legacy_filter_metadata%', ]); $services->set('api_platform.metadata.resource.metadata_collection_factory.cached', CachedResourceMetadataCollectionFactory::class)