Skip to content

Commit c5ddd70

Browse files
committed
fix: fix ExactFilter
Fixes #7478
1 parent 345ebd9 commit c5ddd70

File tree

3 files changed

+39
-16
lines changed

3 files changed

+39
-16
lines changed

src/Doctrine/Orm/Filter/ExactFilter.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,25 @@ final class ExactFilter implements FilterInterface, OpenApiParameterFilterInterf
3131
public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
3232
{
3333
$parameter = $context['parameter'];
34-
$value = $parameter->getValue();
35-
$property = $parameter->getProperty();
3634
$alias = $queryBuilder->getRootAliases()[0];
37-
$parameterName = $queryNameGenerator->generateParameterName($property);
38-
39-
if (\is_array($value)) {
40-
$queryBuilder
41-
->{$context['whereClause'] ?? 'andWhere'}(\sprintf('%s.%s IN (:%s)', $alias, $property, $parameterName));
42-
} else {
43-
$queryBuilder
44-
->{$context['whereClause'] ?? 'andWhere'}(\sprintf('%s.%s = :%s', $alias, $property, $parameterName));
35+
$properties = $parameter->getProperties() ?? [$parameter->getProperty()];
36+
foreach ($properties as $property) {
37+
$parameterName = $queryNameGenerator->generateParameterName($property);
38+
$values = $parameter->getValue();
39+
40+
if (is_iterable($values)) {
41+
$queryBuilder
42+
->{$context['whereClause'] ?? 'andWhere'}(
43+
\sprintf('%s.%s IN (:%s)', $alias, $property, $parameterName)
44+
);
45+
} else {
46+
$queryBuilder
47+
->{$context['whereClause'] ?? 'andWhere'}(
48+
\sprintf('%s.%s = :%s', $alias, $property, $parameterName)
49+
);
50+
}
51+
52+
$queryBuilder->setParameter($parameterName, $values);
4553
}
46-
47-
$queryBuilder->setParameter($parameterName, $value);
4854
}
4955
}

tests/Fixtures/TestBundle/Entity/SearchFilterParameter.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity;
1515

16+
use ApiPlatform\Doctrine\Orm\Filter\ExactFilter;
1617
use ApiPlatform\Doctrine\Orm\Filter\PartialSearchFilter;
1718
use ApiPlatform\Metadata\ApiFilter;
1819
use ApiPlatform\Metadata\ApiResource;
@@ -35,10 +36,14 @@
3536
'searchPartial[:property]' => new QueryParameter(filter: 'app_search_filter_partial'),
3637
'searchExact[:property]' => new QueryParameter(filter: 'app_search_filter_with_exact'),
3738
'searchOnTextAndDate[:property]' => new QueryParameter(filter: 'app_filter_date_and_search'),
38-
'searchParameter[:property]' => new QueryParameter(
39+
'searchPartialProperties[:property]' => new QueryParameter(
3940
filter : new PartialSearchFilter(),
4041
properties: ['foo'],
4142
),
43+
'searchExactProperties[:property]' => new QueryParameter(
44+
filter: new ExactFilter(),
45+
properties: ['foo'],
46+
),
4247
'q' => new QueryParameter(property: 'hydra:freetextQuery'),
4348
]
4449
)]

tests/Functional/Parameters/DoctrineTest.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function testDoctrineEntitySearchFilter(): void
4949
$this->assertEquals('bar', $a['hydra:member'][1]['foo']);
5050

5151
$this->assertArraySubset(['hydra:search' => [
52-
'hydra:template' => \sprintf('/%s{?foo,fooAlias,order[order[id]],order[order[foo]],searchPartial[foo],searchExact[foo],searchOnTextAndDate[foo],searchOnTextAndDate[createdAt][before],searchOnTextAndDate[createdAt][strictly_before],searchOnTextAndDate[createdAt][after],searchOnTextAndDate[createdAt][strictly_after],searchParameter[foo],q,id,createdAt}', $route),
52+
'hydra:template' => \sprintf('/%s{?foo,fooAlias,order[order[id]],order[order[foo]],searchPartial[foo],searchExact[foo],searchOnTextAndDate[foo],searchOnTextAndDate[createdAt][before],searchOnTextAndDate[createdAt][strictly_before],searchOnTextAndDate[createdAt][after],searchOnTextAndDate[createdAt][strictly_after],searchPartialProperties[foo],searchExactProperties[foo],q,id,createdAt}', $route),
5353
]], $a);
5454

5555
$this->assertArraySubset(['@type' => 'IriTemplateMapping', 'variable' => 'fooAlias', 'property' => 'foo'], $a['hydra:search']['hydra:mapping'][1]);
@@ -118,14 +118,26 @@ public function testPropertyPlaceholderFilter(): void
118118
$this->assertEquals($a['hydra:member'][0]['foo'], 'baz');
119119
}
120120

121-
public function testPartialSearchFilter(): void
121+
public function testPartialSearchFilterWithProperties(): void
122122
{
123123
static::bootKernel();
124124
$resource = $this->isMongoDB() ? SearchFilterParameterDocument::class : SearchFilterParameter::class;
125125
$this->recreateSchema([$resource]);
126126
$this->loadFixtures($resource);
127127
$route = 'search_filter_parameter';
128-
$response = self::createClient()->request('GET', $route.'?searchParameter[foo]=baz');
128+
$response = self::createClient()->request('GET', $route.'?searchPartialProperties[foo]=baz');
129+
$a = $response->toArray();
130+
$this->assertEquals($a['hydra:member'][0]['foo'], 'baz');
131+
}
132+
133+
public function testExactFilterWithProperties(): void
134+
{
135+
static::bootKernel();
136+
$resource = $this->isMongoDB() ? SearchFilterParameterDocument::class : SearchFilterParameter::class;
137+
$this->recreateSchema([$resource]);
138+
$this->loadFixtures($resource);
139+
$route = 'search_filter_parameter';
140+
$response = self::createClient()->request('GET', $route.'?searchExactProperties[foo]=baz');
129141
$a = $response->toArray();
130142
$this->assertEquals($a['hydra:member'][0]['foo'], 'baz');
131143
}

0 commit comments

Comments
 (0)