diff --git a/src/Doctrine/Orm/Extension/ParameterExtension.php b/src/Doctrine/Orm/Extension/ParameterExtension.php index ba39b4a776..20f28987b1 100644 --- a/src/Doctrine/Orm/Extension/ParameterExtension.php +++ b/src/Doctrine/Orm/Extension/ParameterExtension.php @@ -14,7 +14,6 @@ namespace ApiPlatform\Doctrine\Orm\Extension; use ApiPlatform\Doctrine\Orm\Filter\FilterInterface; -use ApiPlatform\Doctrine\Orm\Filter\OrderFilter; use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface; use ApiPlatform\Exception\InvalidArgumentException; use ApiPlatform\Metadata\HeaderParameterInterface; @@ -31,7 +30,8 @@ public function __construct(private readonly ContainerInterface $filterLocator) { } - private function applyFilter(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, ?string $resourceClass = null, ?Operation $operation = null, array $context = []) { + private function applyFilter(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, ?string $resourceClass = null, ?Operation $operation = null, array $context = []): void + { if (!($request = $context['request'] ?? null)) { return; } @@ -51,9 +51,10 @@ private function applyFilter(QueryBuilder $queryBuilder, QueryNameGeneratorInter continue; } + $value = $parameters[$key]; $filter = $this->filterLocator->has($filterId) ? $this->filterLocator->get($filterId) : null; if ($filter instanceof FilterInterface) { - $filter->apply($queryBuilder, $queryNameGenerator, $resourceClass, $operation, ['filters' => [$parameter->getProperty() ?? $key => $parameters[$key]]] + $context); + $filter->apply($queryBuilder, $queryNameGenerator, $resourceClass, $operation, ['filters' => [$key => $value]] + $context); } } } diff --git a/src/Hydra/Serializer/CollectionFiltersNormalizer.php b/src/Hydra/Serializer/CollectionFiltersNormalizer.php index 54f6cbcd93..621baccf04 100644 --- a/src/Hydra/Serializer/CollectionFiltersNormalizer.php +++ b/src/Hydra/Serializer/CollectionFiltersNormalizer.php @@ -128,7 +128,7 @@ public function normalize(mixed $object, ?string $format = null, array $context } } - if ($currentFilters || $parameters) { + if ($currentFilters || ($parameters && \count($parameters))) { $data['hydra:search'] = $this->getSearch($resourceClass, $requestParts, $currentFilters, $parameters); } @@ -151,7 +151,7 @@ public function setNormalizer(NormalizerInterface $normalizer): void * @param LegacyFilterInterface[]|FilterInterface[] $filters * @param array $parameters */ - private function getSearch(string $resourceClass, array $parts, array $filters, null|array|Parameters $parameters): array + private function getSearch(string $resourceClass, array $parts, array $filters, array|Parameters|null $parameters): array { $variables = []; $mapping = []; @@ -164,12 +164,26 @@ private function getSearch(string $resourceClass, array $parts, array $filters, foreach ($parameters ?? [] as $key => $parameter) { // Each IriTemplateMapping maps a variable used in the template to a property - if (!$parameter instanceof QueryParameterInterface || !($property = $parameter->getProperty())) { + if (!$parameter instanceof QueryParameterInterface) { + continue; + } + + if (!($property = $parameter->getProperty()) && ($filterId = $parameter->getFilter())) { + $filter = $this->getFilter($filterId); + foreach ($filter->getDescription($resourceClass) as $variable => $description) { + $variables[] = $variable; + $m = ['@type' => 'IriTemplateMapping', 'variable' => $variable, 'property' => $description['property'], 'required' => $description['required']]; + if (null !== ($required = $parameter->getRequired())) { + $m['required'] = $required; + } + $mapping[] = $m; + } + continue; } - $variables[] = $key; $m = ['@type' => 'IriTemplateMapping', 'variable' => $key, 'property' => $property]; + $variables[] = $key; if (null !== ($required = $parameter->getRequired())) { $m['required'] = $required; } diff --git a/src/Metadata/ApiResource.php b/src/Metadata/ApiResource.php index 2907cc5d47..f95508a5ca 100644 --- a/src/Metadata/ApiResource.php +++ b/src/Metadata/ApiResource.php @@ -960,7 +960,7 @@ public function __construct( $provider = null, $processor = null, protected ?OptionsInterface $stateOptions = null, - protected null|array|Parameters $parameters = null, + protected array|Parameters|null $parameters = null, protected array $extraProperties = [], ) { parent::__construct( diff --git a/src/Metadata/Delete.php b/src/Metadata/Delete.php index eeeaa18700..3add06dc84 100644 --- a/src/Metadata/Delete.php +++ b/src/Metadata/Delete.php @@ -94,7 +94,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], ) { parent::__construct( diff --git a/src/Metadata/Extractor/XmlResourceExtractor.php b/src/Metadata/Extractor/XmlResourceExtractor.php index 48c71dde34..e92785331a 100644 --- a/src/Metadata/Extractor/XmlResourceExtractor.php +++ b/src/Metadata/Extractor/XmlResourceExtractor.php @@ -535,7 +535,7 @@ private function buildParameters(\SimpleXMLElement $resource): ?array property: $this->phpize($parameter, 'property', 'string'), description: $this->phpize($parameter, 'description', 'string'), priority: $this->phpize($parameter, 'priority', 'integer'), - extraProperties: $this->buildExtraProperties($parameter, 'extraProperties'), + extraProperties: $this->buildExtraProperties($parameter, 'extraProperties') ?? [], ); } diff --git a/src/Metadata/Extractor/YamlResourceExtractor.php b/src/Metadata/Extractor/YamlResourceExtractor.php index 089b0f643e..da539bea85 100644 --- a/src/Metadata/Extractor/YamlResourceExtractor.php +++ b/src/Metadata/Extractor/YamlResourceExtractor.php @@ -470,7 +470,7 @@ private function buildParameters(array $resource): ?array key: $key, required: $this->phpize($parameter, 'required', 'bool'), schema: $parameter['schema'], - openapi: ($parameter['openapi'] ?? null) ? new Parameter( + openApi: ($parameter['openapi'] ?? null) ? new Parameter( name: $parameter['openapi']['name'], in: $parameter['in'] ?? 'query', description: $parameter['openapi']['description'] ?? '', @@ -490,7 +490,7 @@ private function buildParameters(array $resource): ?array property: $this->phpize($parameter, 'property', 'string'), description: $this->phpize($parameter, 'description', 'string'), priority: $this->phpize($parameter, 'priority', 'integer'), - extraProperties: $this->buildArrayValue($resource, 'extraProperties'), + extraProperties: $this->buildArrayValue($parameter, 'extraProperties') ?? [], ); } diff --git a/src/Metadata/Get.php b/src/Metadata/Get.php index 0a60f21f34..2bd4779581 100644 --- a/src/Metadata/Get.php +++ b/src/Metadata/Get.php @@ -94,7 +94,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], ) { parent::__construct( diff --git a/src/Metadata/GetCollection.php b/src/Metadata/GetCollection.php index 74ba34c6cf..c83324f45d 100644 --- a/src/Metadata/GetCollection.php +++ b/src/Metadata/GetCollection.php @@ -94,7 +94,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], private ?string $itemUriTemplate = null, ) { diff --git a/src/Metadata/GraphQl/Operation.php b/src/Metadata/GraphQl/Operation.php index 3b502a5d37..84bfde686a 100644 --- a/src/Metadata/GraphQl/Operation.php +++ b/src/Metadata/GraphQl/Operation.php @@ -85,7 +85,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [] ) { parent::__construct( diff --git a/src/Metadata/GraphQl/Query.php b/src/Metadata/GraphQl/Query.php index 288968d7a6..7fe85a73db 100644 --- a/src/Metadata/GraphQl/Query.php +++ b/src/Metadata/GraphQl/Query.php @@ -69,7 +69,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], protected ?bool $nested = null, diff --git a/src/Metadata/GraphQl/QueryCollection.php b/src/Metadata/GraphQl/QueryCollection.php index f1d9cf6606..4a5b94b060 100644 --- a/src/Metadata/GraphQl/QueryCollection.php +++ b/src/Metadata/GraphQl/QueryCollection.php @@ -70,7 +70,7 @@ public function __construct( $provider = null, $processor = null, protected ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], ?bool $nested = null, diff --git a/src/Metadata/GraphQl/Subscription.php b/src/Metadata/GraphQl/Subscription.php index eade951a50..4449f5fde7 100644 --- a/src/Metadata/GraphQl/Subscription.php +++ b/src/Metadata/GraphQl/Subscription.php @@ -69,7 +69,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], ) { parent::__construct( diff --git a/src/Metadata/HttpOperation.php b/src/Metadata/HttpOperation.php index ce12e9c58b..39851d28b4 100644 --- a/src/Metadata/HttpOperation.php +++ b/src/Metadata/HttpOperation.php @@ -200,7 +200,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], ) { parent::__construct( diff --git a/src/Metadata/Metadata.php b/src/Metadata/Metadata.php index 2472480353..ab52445aac 100644 --- a/src/Metadata/Metadata.php +++ b/src/Metadata/Metadata.php @@ -21,15 +21,15 @@ abstract class Metadata { /** - * @param string|null $deprecationReason https://api-platform.com/docs/core/deprecations/#deprecating-resource-classes-operations-and-properties - * @param string|null $security https://api-platform.com/docs/core/security - * @param string|null $securityPostDenormalize https://api-platform.com/docs/core/security/#executing-access-control-rules-after-denormalization - * @param mixed|null $mercure - * @param mixed|null $messenger - * @param mixed|null $input - * @param mixed|null $output - * @param mixed|null $provider - * @param mixed|null $processor + * @param string|null $deprecationReason https://api-platform.com/docs/core/deprecations/#deprecating-resource-classes-operations-and-properties + * @param string|null $security https://api-platform.com/docs/core/security + * @param string|null $securityPostDenormalize https://api-platform.com/docs/core/security/#executing-access-control-rules-after-denormalization + * @param mixed|null $mercure + * @param mixed|null $messenger + * @param mixed|null $input + * @param mixed|null $output + * @param mixed|null $provider + * @param mixed|null $processor * @param Parameters|array $parameters */ public function __construct( @@ -73,7 +73,7 @@ public function __construct( /** * @experimental */ - protected null|array|Parameters $parameters = [], + protected array|Parameters|null $parameters = [], protected array $extraProperties = [] ) { } @@ -574,7 +574,7 @@ public function withStateOptions(?OptionsInterface $stateOptions): static /** * @return array */ - public function getParameters(): null|array|Parameters + public function getParameters(): array|Parameters|null { return $this->parameters; } diff --git a/src/Metadata/Operation.php b/src/Metadata/Operation.php index f4582c8c72..105b9f5ddd 100644 --- a/src/Metadata/Operation.php +++ b/src/Metadata/Operation.php @@ -806,7 +806,7 @@ public function __construct( protected $provider = null, protected $processor = null, protected ?OptionsInterface $stateOptions = null, - protected null|array|Parameters $parameters = [], + protected array|Parameters|null $parameters = [], protected array $extraProperties = [], ) { parent::__construct( diff --git a/src/Metadata/Parameter.php b/src/Metadata/Parameter.php index 832f840a83..d0e9bb8c06 100644 --- a/src/Metadata/Parameter.php +++ b/src/Metadata/Parameter.php @@ -37,7 +37,7 @@ public function __construct( protected ?string $description = null, protected ?bool $required = null, protected ?int $priority = null, - protected array $extraProperties = [], + protected ?array $extraProperties = [], ) { } diff --git a/src/Metadata/Parameters.php b/src/Metadata/Parameters.php index f0b6afdbf8..6c1e9902d2 100644 --- a/src/Metadata/Parameters.php +++ b/src/Metadata/Parameters.php @@ -15,6 +15,8 @@ /** * An parameter dictionnary. + * + * @implements \IteratorAggregate */ final class Parameters implements \IteratorAggregate, \Countable { @@ -36,6 +38,9 @@ public function __construct(array $parameters = []) $this->sort(); } + /** + * @return \ArrayIterator + */ public function getIterator(): \Traversable { return (function (): \Generator { diff --git a/src/Metadata/Patch.php b/src/Metadata/Patch.php index 043c07db62..3d6ba4bf02 100644 --- a/src/Metadata/Patch.php +++ b/src/Metadata/Patch.php @@ -94,7 +94,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], ) { parent::__construct( diff --git a/src/Metadata/Post.php b/src/Metadata/Post.php index 3d609f4adc..58e49a4a65 100644 --- a/src/Metadata/Post.php +++ b/src/Metadata/Post.php @@ -94,7 +94,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], private ?string $itemUriTemplate = null ) { diff --git a/src/Metadata/Put.php b/src/Metadata/Put.php index b487493b36..1c0753f8c0 100644 --- a/src/Metadata/Put.php +++ b/src/Metadata/Put.php @@ -94,7 +94,7 @@ public function __construct( $provider = null, $processor = null, ?OptionsInterface $stateOptions = null, - null|array|Parameters $parameters = null, + array|Parameters|null $parameters = null, array $extraProperties = [], private ?bool $allowCreate = null, ) { diff --git a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php index af5f952e11..77b41c0c4d 100644 --- a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php +++ b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php @@ -19,7 +19,6 @@ use ApiPlatform\Metadata\Resource\ResourceMetadataCollection; use ApiPlatform\OpenApi; use ApiPlatform\Serializer\Filter\FilterInterface as SerializerFilterInterface; -use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\WithParameter; use Psr\Container\ContainerInterface; /** @@ -57,11 +56,11 @@ public function create(string $resourceClass): ResourceMetadataCollection // Read filter description to populate the Parameter $description = $filter instanceof FilterInterface ? $filter->getDescription($resourceClass) : []; - if (($schema = $description['schema'] ?? null) && null === $parameter->getSchema()) { + if (($schema = $description[$key]['schema'] ?? null) && null === $parameter->getSchema()) { $parameter = $parameter->withSchema($schema); } - if (null === $parameter->getOpenApi() && $openApi = $description['openapi'] ?? null) { + if (null === $parameter->getOpenApi() && $openApi = $description[$key]['openapi'] ?? null) { if ($openApi instanceof OpenApi\Model\Parameter) { $parameter = $parameter->withOpenApi($openApi); } @@ -70,8 +69,8 @@ public function create(string $resourceClass): ResourceMetadataCollection $parameter->withOpenApi(new OpenApi\Model\Parameter( $key, $parameter instanceof HeaderParameterInterface ? 'header' : 'query', - $description['description'] ?? '', - $description['required'] ?? $openApi['required'] ?? false, + $description[$key]['description'] ?? '', + $description[$key]['required'] ?? $openApi['required'] ?? false, $openApi['deprecated'] ?? false, $openApi['allowEmptyValue'] ?? true, $schema, @@ -97,25 +96,4 @@ public function create(string $resourceClass): ResourceMetadataCollection return $resourceMetadataCollection; } - - /** - * @return Iterable - */ - private function getIterator(null|array|\SplPriorityQueue $parameters): Iterable { - if (!$parameters) { - return []; - } - - if (is_array($parameters)) { - foreach ($parameters as $key => $parameter) { - yield $key => $parameter; - } - - return $parameters; - } - - foreach ($parameters as $priority => $parameter) { - yield $parameter->getKey() => $parameter->withPriority($priority); - } - } } diff --git a/src/Metadata/Tests/Extractor/XmlExtractorTest.php b/src/Metadata/Tests/Extractor/XmlExtractorTest.php index c38dbd802c..be195c2b97 100644 --- a/src/Metadata/Tests/Extractor/XmlExtractorTest.php +++ b/src/Metadata/Tests/Extractor/XmlExtractorTest.php @@ -386,7 +386,7 @@ public function testValidXML(): void schema: [ 'type' => 'string', ], - extraProperties: [] + extraProperties: ['foo' => 'bar'] ), ], ], diff --git a/src/Metadata/Tests/Extractor/YamlExtractorTest.php b/src/Metadata/Tests/Extractor/YamlExtractorTest.php index 06fa95940b..ea891fa654 100644 --- a/src/Metadata/Tests/Extractor/YamlExtractorTest.php +++ b/src/Metadata/Tests/Extractor/YamlExtractorTest.php @@ -405,7 +405,7 @@ public function testValidYaml(): void 'stateOptions' => null, 'links' => null, 'headers' => ['hello' => 'world'], - 'parameters' => ['author' => new QueryParameter(schema: ['type' => 'string'], required: true, key: 'author')], + 'parameters' => ['author' => new QueryParameter(schema: ['type' => 'string'], required: true, key: 'author', description: 'hello')], ], ], 'graphQlOperations' => null, diff --git a/src/OpenApi/Factory/OpenApiFactory.php b/src/OpenApi/Factory/OpenApiFactory.php index 4534ec429f..b059d9c183 100644 --- a/src/OpenApi/Factory/OpenApiFactory.php +++ b/src/OpenApi/Factory/OpenApiFactory.php @@ -308,9 +308,9 @@ private function collectPaths(ApiResource $resource, ResourceMetadataCollection } $openapiParameters = $openapiOperation->getParameters(); - foreach ($operation->getParameters() ?? [] as $p) { + foreach ($operation->getParameters() ?? [] as $key => $p) { $in = $p instanceof HeaderParameterInterface ? 'header' : 'query'; - $parameter = new Parameter($p->getKey(), $in, $p->getDescription() ?? "$resourceShortName $key", $p->getRequired() ?? false, false, false, $p->getSchema() ?? ['type' => 'string']); + $parameter = new Parameter($key, $in, $p->getDescription() ?? "$resourceShortName $key", $p->getRequired() ?? false, false, false, $p->getSchema() ?? ['type' => 'string']); if ($linkParameter = $p->getOpenApi()) { $parameter = $this->mergeParameter($parameter, $linkParameter); diff --git a/tests/Fixtures/TestBundle/ApiResource/WithParameter.php b/tests/Fixtures/TestBundle/ApiResource/WithParameter.php index 638095fbcc..7b6a210c92 100644 --- a/tests/Fixtures/TestBundle/ApiResource/WithParameter.php +++ b/tests/Fixtures/TestBundle/ApiResource/WithParameter.php @@ -37,6 +37,7 @@ 'auth' => new HeaderParameter(provider: [self::class, 'restrictAccess']), 'priority' => new QueryParameter(provider: [self::class, 'assertSecond'], priority: 10), 'priorityb' => new QueryParameter(provider: [self::class, 'assertFirst'], priority: 20), + 'array' => new QueryParameter(provider: [self::class, 'assertArray']), ], provider: [self::class, 'provide'] )] @@ -49,7 +50,7 @@ )] class WithParameter { - private static int $counter = 1; + public static int $counter = 1; public int $id = 1; #[Groups(['a'])] @@ -67,15 +68,19 @@ public static function provide() return new self(); } - public static function assertFirst() + public static function assertArray(): void { - assert(static::$counter === 1); - static::$counter++; } - public static function assertSecond() + public static function assertFirst(): void { - assert(static::$counter === 2); + \assert(1 === static::$counter); + ++static::$counter; + } + + public static function assertSecond(): void + { + \assert(2 === static::$counter); } public static function provideGroup(Parameter $parameter, array $parameters = [], array $context = []) diff --git a/tests/Fixtures/TestBundle/Entity/SearchFilterParameter.php b/tests/Fixtures/TestBundle/Entity/SearchFilterParameter.php index 7a29adcd9a..7d8525cca2 100644 --- a/tests/Fixtures/TestBundle/Entity/SearchFilterParameter.php +++ b/tests/Fixtures/TestBundle/Entity/SearchFilterParameter.php @@ -1,5 +1,16 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity; use ApiPlatform\Metadata\GetCollection; @@ -7,9 +18,10 @@ use Doctrine\ORM\Mapping as ORM; #[GetCollection( - uriTemplate: 'search_filter_parameter', + uriTemplate: 'search_filter_parameter{._format}', parameters: [ - 'search' => new QueryParameter(filter: 'app_search_filter_via_parameter', property: 'foo'), + 'foo' => new QueryParameter(filter: 'app_search_filter_via_parameter'), + 'order' => new QueryParameter(filter: 'app_search_filter_via_parameter.order_filter'), ] )] #[ORM\Entity] diff --git a/tests/Fixtures/app/AppKernel.php b/tests/Fixtures/app/AppKernel.php index 041db0c810..34e151c88a 100644 --- a/tests/Fixtures/app/AppKernel.php +++ b/tests/Fixtures/app/AppKernel.php @@ -124,7 +124,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load 'session' => class_exists(SessionFactory::class) ? ['storage_factory_id' => 'session.storage.factory.mock_file'] + $cookie : ['storage_id' => 'session.storage.mock_file'] + $cookie, 'profiler' => [ 'enabled' => true, - 'collect' => false, + 'collect' => true, ], 'php_errors' => ['log' => true], 'messenger' => $messengerConfig, @@ -143,7 +143,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load 'session' => class_exists(SessionFactory::class) ? ['storage_factory_id' => 'session.storage.factory.mock_file'] : ['storage_id' => 'session.storage.mock_file'], 'profiler' => [ 'enabled' => true, - 'collect' => false, + 'collect' => true, ], 'messenger' => $messengerConfig, 'router' => ['utf8' => true], diff --git a/tests/Fixtures/app/config/config_common.yml b/tests/Fixtures/app/config/config_common.yml index 332099bc07..7bd2b6b82a 100644 --- a/tests/Fixtures/app/config/config_common.yml +++ b/tests/Fixtures/app/config/config_common.yml @@ -450,8 +450,3 @@ services: tags: - name: 'api_platform.parameter_provider' key: 'ApiPlatform\Tests\Fixtures\TestBundle\Parameter\CustomGroupParameterProvider' - - app_search_filter_via_parameter: - parent: 'api_platform.doctrine.orm.search_filter' - arguments: [ { foo: 'exact' } ] - tags: [ { name: 'api_platform.filter', id: 'app_search_filter_via_parameter' } ] diff --git a/tests/Fixtures/app/config/config_doctrine.yml b/tests/Fixtures/app/config/config_doctrine.yml index f6b3363176..929fb6289e 100644 --- a/tests/Fixtures/app/config/config_doctrine.yml +++ b/tests/Fixtures/app/config/config_doctrine.yml @@ -135,3 +135,13 @@ services: - name: 'api_platform.state_provider' arguments: $itemProvider: '@ApiPlatform\Doctrine\Orm\State\ItemProvider' + + app_search_filter_via_parameter: + parent: 'api_platform.doctrine.orm.search_filter' + arguments: [ { foo: 'exact' } ] + tags: [ { name: 'api_platform.filter', id: 'app_search_filter_via_parameter' } ] + + app_search_filter_via_parameter.order_filter: + parent: 'api_platform.doctrine.orm.order_filter' + arguments: [ { id: 'ASC', foo: 'DESC' } ] + tags: [ 'api_platform.filter' ] diff --git a/tests/Parameter/ParameterTests.php b/tests/Parameter/ParameterTests.php index f472bed174..8617229932 100644 --- a/tests/Parameter/ParameterTests.php +++ b/tests/Parameter/ParameterTests.php @@ -15,6 +15,7 @@ use ApiPlatform\Symfony\Bundle\Test\ApiTestCase; use ApiPlatform\Tests\Fixtures\TestBundle\Entity\SearchFilterParameter; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\SchemaTool; final class ParameterTests extends ApiTestCase @@ -64,7 +65,10 @@ public function testHydraTemplate(): void public function testDoctrineEntitySearchFilter(): void { - $this->recreateSchema(); + if (false === $this->recreateSchema()) { + $this->markTestSkipped(); + } + $registry = $this->getContainer()->get('doctrine'); $entityManager = $registry->getManagerForClass(SearchFilterParameter::class); @@ -75,32 +79,38 @@ public function testDoctrineEntitySearchFilter(): void } $entityManager->flush(); - $response = self::createClient()->request('GET', 'search_filter_parameter?search=bar'); + $response = self::createClient()->request('GET', 'search_filter_parameter?foo=bar'); $a = $response->toArray(); $this->assertCount(2, $a['hydra:member']); $this->assertEquals('bar', $a['hydra:member'][0]['foo']); $this->assertEquals('bar', $a['hydra:member'][1]['foo']); $this->assertArraySubset(['hydra:search' => [ - 'hydra:template' => '/search_filter_parameter{?search}', + 'hydra:template' => '/search_filter_parameter{?foo,foo[],order[id],order[foo]}', 'hydra:mapping' => [ - ['@type' => 'IriTemplateMapping', 'variable' => 'search', 'property' => 'foo'], + ['@type' => 'IriTemplateMapping', 'variable' => 'foo', 'property' => 'foo'], ], ]], $a); + + $response = self::createClient()->request('GET', 'search_filter_parameter?order[foo]=asc'); + $this->assertEquals($response->toArray()['hydra:member'][0]['foo'], 'bar'); } - private function recreateSchema(array $options = []): void + /** + * @param array $options kernel options + */ + private function recreateSchema(array $options = []): ?bool { self::bootKernel($options); - /** @var EntityManagerInterface $manager */ - $manager = static::getContainer()->get('doctrine')->getManager(); - /** @var ClassMetadata[] $classes */ - $classes = $manager->getMetadataFactory()->getAllMetadata(); - $schemaTool = new SchemaTool($manager); + $manager = static::getContainer()->get('doctrine')->getManagerForClass(SearchFilterParameter::class); + if (!$manager instanceof EntityManagerInterface) { + return false; + } - @$schemaTool->dropSchema($classes); - @$schemaTool->createSchema($classes); + $classes = $manager->getClassMetadata(SearchFilterParameter::class); + $schemaTool = new SchemaTool($manager); + @$schemaTool->dropSchema([$classes]); + @$schemaTool->createSchema([$classes]); } - } diff --git a/tests/Symfony/Bundle/Test/ClientTest.php b/tests/Symfony/Bundle/Test/ClientTest.php index 8dc41114b2..6c50d8258c 100644 --- a/tests/Symfony/Bundle/Test/ClientTest.php +++ b/tests/Symfony/Bundle/Test/ClientTest.php @@ -112,7 +112,7 @@ public static function authBasicProvider(): iterable public function testComplexScenario(): void { - self::createClient()->request('GET', '/secured_dummies', ['auth_basic' => ['dunglas', 'kevin']]); + $r = self::createClient()->request('GET', '/secured_dummies', ['auth_basic' => ['dunglas', 'kevin']]); $this->assertResponseIsSuccessful(); $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');