Skip to content

Commit 8f255e3

Browse files
committed
fixes
1 parent 61e1b9a commit 8f255e3

25 files changed

+339
-295
lines changed

src/Doctrine/Odm/Filter/ExactFilter.php

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,24 @@ public function apply(Builder $aggregationBuilder, string $resourceClass, ?Opera
6060
}
6161

6262
$mapping = $classMetadata->getFieldMapping($property);
63-
$targetDocument = $mapping['targetDocument'];
64-
$repository = $documentManager->getRepository($targetDocument);
65-
$method = $classMetadata->isCollectionValuedAssociation($property) ? 'includesReferenceTo' : 'references';
63+
$method = $classMetadata->isSingleValuedAssociation($property) ? 'references' : 'includesReferenceTo';
6664

6765
if (is_iterable($value)) {
68-
$documents = [];
69-
foreach ($value as $v) {
70-
if ($doc = $repository->find($v)) {
71-
$documents[] = $doc;
72-
}
73-
}
74-
7566
$match = $aggregationBuilder->match();
7667
$or = $match->expr();
77-
foreach ($documents as $doc) {
78-
$or->addOr($match->expr()->field($property)->{$method}($doc));
68+
69+
foreach ($value as $v) {
70+
$or->addOr($match->expr()->field($property)->{$method}($documentManager->getPartialReference($mapping['targetDocument'], $v)));
7971
}
72+
8073
$match->addAnd($or);
8174

8275
return;
8376
}
8477

85-
$referencedDoc = $repository->find($value);
86-
8778
$aggregationBuilder
8879
->match()
8980
->field($property)
90-
->{$method}($referencedDoc);
81+
->{$method}($documentManager->getPartialReference($mapping['targetDocument'], $value));
9182
}
9283
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Doctrine\Odm\Filter;
15+
16+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareInterface;
17+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareTrait;
18+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareInterface;
19+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareTrait;
20+
use ApiPlatform\Metadata\BackwardCompatibleFilterDescriptionTrait;
21+
use ApiPlatform\Metadata\Operation;
22+
use Doctrine\ODM\MongoDB\Aggregation\Builder;
23+
24+
final class FreeTextQueryFilter implements FilterInterface, ManagerRegistryAwareInterface, LoggerAwareInterface
25+
{
26+
use BackwardCompatibleFilterDescriptionTrait;
27+
use LoggerAwareTrait;
28+
use ManagerRegistryAwareTrait;
29+
30+
/**
31+
* @param list<string> $properties an array of properties, defaults to `parameter->getProperties()`
32+
*/
33+
public function __construct(private readonly FilterInterface $filter, private readonly ?array $properties = null)
34+
{
35+
}
36+
37+
public function apply(Builder $aggregationBuilder, string $resourceClass, ?Operation $operation = null, array &$context = []): void
38+
{
39+
if ($this->filter instanceof ManagerRegistryAwareInterface) {
40+
$this->filter->setManagerRegistry($this->getManagerRegistry());
41+
}
42+
43+
if ($this->filter instanceof LoggerAwareInterface) {
44+
$this->filter->setLogger($this->getLogger());
45+
}
46+
47+
$parameter = $context['parameter'];
48+
foreach ($this->properties ?? $parameter->getProperties() ?? [] as $property) {
49+
$this->filter->apply(
50+
$aggregationBuilder,
51+
$resourceClass,
52+
$operation,
53+
['parameter' => $parameter->withProperty($property)] + $context
54+
);
55+
}
56+
}
57+
}

src/Doctrine/Odm/Filter/IriFilter.php

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
use Doctrine\ODM\MongoDB\Aggregation\Builder;
2525
use Doctrine\ODM\MongoDB\DocumentManager;
2626
use Doctrine\ODM\MongoDB\Mapping\MappingException;
27-
use Symfony\Component\PropertyAccess\PropertyAccess;
2827

2928
/**
3029
* @author Vincent Amstoutz <[email protected]>
@@ -41,7 +40,6 @@ final class IriFilter implements FilterInterface, OpenApiParameterFilterInterfac
4140
public function apply(Builder $aggregationBuilder, string $resourceClass, ?Operation $operation = null, array &$context = []): void
4241
{
4342
$parameter = $context['parameter'];
44-
$property = $parameter->getProperty();
4543
$value = $parameter->getValue();
4644

4745
$documentManager = $this->getManagerRegistry()->getManagerForClass($resourceClass);
@@ -50,38 +48,12 @@ public function apply(Builder $aggregationBuilder, string $resourceClass, ?Opera
5048
}
5149

5250
$classMetadata = $documentManager->getClassMetadata($resourceClass);
51+
$property = $parameter->getProperty();
5352
if (!$classMetadata->hasReference($property)) {
5453
return;
5554
}
5655

57-
$mapping = $classMetadata->getFieldMapping($property);
58-
59-
if (isset($mapping['mappedBy'])) {
60-
$propertyAccessor = PropertyAccess::createPropertyAccessor();
61-
$mappedByProperty = $mapping['mappedBy'];
62-
$identifier = '_id';
63-
64-
if (is_iterable($value)) {
65-
$ids = [];
66-
foreach ($value as $v) {
67-
if ($relatedDoc = $propertyAccessor->getValue($v, $mappedByProperty)) {
68-
$ids[] = $propertyAccessor->getValue($relatedDoc, 'id');
69-
}
70-
}
71-
72-
$aggregationBuilder->match()->field($identifier)->in($ids);
73-
74-
return;
75-
}
76-
77-
if ($relatedDoc = $propertyAccessor->getValue($value, $mappedByProperty)) {
78-
$aggregationBuilder->match()->field($identifier)->equals($propertyAccessor->getValue($relatedDoc, 'id'));
79-
}
80-
81-
return;
82-
}
83-
84-
$method = $classMetadata->isCollectionValuedAssociation($property) ? 'includesReferenceTo' : 'references';
56+
$method = $classMetadata->isSingleValuedAssociation($property) ? 'references' : 'includesReferenceTo';
8557

8658
if (is_iterable($value)) {
8759
$match = $aggregationBuilder->match();

src/Doctrine/Odm/Filter/OrFilter.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
namespace ApiPlatform\Doctrine\Odm\Filter;
1515

16+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareInterface;
17+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareTrait;
18+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareInterface;
19+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareTrait;
1620
use ApiPlatform\Doctrine\Common\Filter\OpenApiFilterTrait;
1721
use ApiPlatform\Metadata\BackwardCompatibleFilterDescriptionTrait;
1822
use ApiPlatform\Metadata\OpenApiParameterFilterInterface;
@@ -22,21 +26,34 @@
2226
/**
2327
* @author Vincent Amstoutz <[email protected]>
2428
*/
25-
final class OrFilter implements FilterInterface, OpenApiParameterFilterInterface
29+
final class OrFilter implements FilterInterface, OpenApiParameterFilterInterface, ManagerRegistryAwareInterface, LoggerAwareInterface
2630
{
2731
use BackwardCompatibleFilterDescriptionTrait;
32+
use LoggerAwareTrait;
33+
use ManagerRegistryAwareTrait;
2834
use OpenApiFilterTrait;
2935

3036
/**
31-
* @param array<FilterInterface> $filters
37+
* @param FilterInterface[] $filters
3238
*/
33-
public function __construct(private readonly array $filters)
39+
private array $filters;
40+
41+
public function __construct(FilterInterface ...$filters)
3442
{
43+
$this->filters = $filters;
3544
}
3645

3746
public function apply(Builder $aggregationBuilder, string $resourceClass, ?Operation $operation = null, array &$context = []): void
3847
{
3948
foreach ($this->filters as $filter) {
49+
if ($filter instanceof ManagerRegistryAwareInterface) {
50+
$filter->setManagerRegistry($this->getManagerRegistry());
51+
}
52+
53+
if ($filter instanceof LoggerAwareInterface) {
54+
$filter->setLogger($this->getLogger());
55+
}
56+
4057
$context = ['whereClause' => 'orWhere'] + $context;
4158
$filter->apply($aggregationBuilder, $resourceClass, $operation, $context);
4259
}

src/Doctrine/Orm/Filter/ExactFilter.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $q
3232
{
3333
$parameter = $context['parameter'];
3434
$value = $parameter->getValue();
35-
3635
$property = $parameter->getProperty();
3736
$alias = $queryBuilder->getRootAliases()[0];
3837
$parameterName = $queryNameGenerator->generateParameterName($property);
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Doctrine\Orm\Filter;
15+
16+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareInterface;
17+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareTrait;
18+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareInterface;
19+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareTrait;
20+
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
21+
use ApiPlatform\Metadata\BackwardCompatibleFilterDescriptionTrait;
22+
use ApiPlatform\Metadata\Operation;
23+
use Doctrine\ORM\QueryBuilder;
24+
25+
final class FreeTextQueryFilter implements FilterInterface, ManagerRegistryAwareInterface, LoggerAwareInterface
26+
{
27+
use BackwardCompatibleFilterDescriptionTrait;
28+
use LoggerAwareTrait;
29+
use ManagerRegistryAwareTrait;
30+
31+
/**
32+
* @param list<string> $properties an array of properties, defaults to `parameter->getProperties()`
33+
*/
34+
public function __construct(private readonly FilterInterface $filter, private readonly ?array $properties = null)
35+
{
36+
}
37+
38+
public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
39+
{
40+
if ($this->filter instanceof ManagerRegistryAwareInterface) {
41+
$this->filter->setManagerRegistry($this->getManagerRegistry());
42+
}
43+
44+
if ($this->filter instanceof LoggerAwareInterface) {
45+
$this->filter->setLogger($this->getLogger());
46+
}
47+
48+
$parameter = $context['parameter'];
49+
foreach ($this->properties ?? $parameter->getProperties() ?? [] as $property) {
50+
$this->filter->apply(
51+
$queryBuilder,
52+
$queryNameGenerator,
53+
$resourceClass,
54+
$operation,
55+
['parameter' => $parameter->withProperty($property)] + $context
56+
);
57+
}
58+
}
59+
}

src/Doctrine/Orm/Filter/IriFilter.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,22 @@ final class IriFilter implements FilterInterface, OpenApiParameterFilterInterfac
3333
public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
3434
{
3535
$parameter = $context['parameter'];
36-
3736
$value = $parameter->getValue();
38-
3937
$property = $parameter->getProperty();
4038
$alias = $queryBuilder->getRootAliases()[0];
4139
$parameterName = $queryNameGenerator->generateParameterName($property);
4240

4341
$queryBuilder->join(\sprintf('%s.%s', $alias, $property), $parameterName);
4442

45-
if (\is_array($value)) {
43+
if (is_iterable($value)) {
4644
$queryBuilder
4745
->{$context['whereClause'] ?? 'andWhere'}(\sprintf('%s IN (:%s)', $parameterName, $parameterName));
46+
$queryBuilder->setParameter($parameterName, $value);
4847
} else {
4948
$queryBuilder
5049
->{$context['whereClause'] ?? 'andWhere'}(\sprintf('%s = :%s', $parameterName, $parameterName));
50+
$queryBuilder->setParameter($parameterName, $value);
5151
}
52-
53-
$queryBuilder->setParameter($parameterName, $value);
5452
}
5553

5654
public static function getParameterProvider(): string

src/Doctrine/Orm/Filter/OrFilter.php

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
namespace ApiPlatform\Doctrine\Orm\Filter;
1515

16+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareInterface;
17+
use ApiPlatform\Doctrine\Common\Filter\LoggerAwareTrait;
18+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareInterface;
19+
use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareTrait;
1620
use ApiPlatform\Doctrine\Common\Filter\OpenApiFilterTrait;
1721
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
1822
use ApiPlatform\Metadata\BackwardCompatibleFilterDescriptionTrait;
@@ -22,29 +26,36 @@
2226

2327
/**
2428
* @author Vincent Amstoutz <[email protected]>
29+
*
30+
* @experimental
2531
*/
26-
final class OrFilter implements FilterInterface, OpenApiParameterFilterInterface
32+
final class OrFilter implements FilterInterface, OpenApiParameterFilterInterface, ManagerRegistryAwareInterface, LoggerAwareInterface
2733
{
2834
use BackwardCompatibleFilterDescriptionTrait;
35+
use LoggerAwareTrait;
36+
use ManagerRegistryAwareTrait;
2937
use OpenApiFilterTrait;
3038

31-
/**
32-
* @param array<FilterInterface> $filters
33-
*/
34-
public function __construct(private readonly array $filters)
39+
public function __construct(private readonly FilterInterface $filter)
3540
{
3641
}
3742

3843
public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
3944
{
40-
foreach ($this->filters as $filter) {
41-
$filter->apply(
42-
$queryBuilder,
43-
$queryNameGenerator,
44-
$resourceClass,
45-
$operation,
46-
['whereClause' => 'orWhere'] + $context
47-
);
45+
if ($this->filter instanceof ManagerRegistryAwareInterface) {
46+
$this->filter->setManagerRegistry($this->getManagerRegistry());
47+
}
48+
49+
if ($this->filter instanceof LoggerAwareInterface) {
50+
$this->filter->setLogger($this->getLogger());
4851
}
52+
53+
$this->filter->apply(
54+
$queryBuilder,
55+
$queryNameGenerator,
56+
$resourceClass,
57+
$operation,
58+
['whereClause' => 'orWhere'] + $context
59+
);
4960
}
5061
}

0 commit comments

Comments
 (0)