|
13 | 13 |
|
14 | 14 | namespace ApiPlatform\Doctrine\Odm\Filter; |
15 | 15 |
|
| 16 | +use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareInterface; |
| 17 | +use ApiPlatform\Doctrine\Common\Filter\ManagerRegistryAwareTrait; |
16 | 18 | use ApiPlatform\Doctrine\Common\Filter\OpenApiFilterTrait; |
17 | 19 | use ApiPlatform\Metadata\BackwardCompatibleFilterDescriptionTrait; |
18 | 20 | use ApiPlatform\Metadata\OpenApiParameterFilterInterface; |
19 | 21 | use ApiPlatform\Metadata\Operation; |
20 | 22 | use ApiPlatform\Metadata\ParameterProviderFilterInterface; |
21 | 23 | use ApiPlatform\State\ParameterProvider\IriConverterParameterProvider; |
22 | 24 | use Doctrine\ODM\MongoDB\Aggregation\Builder; |
| 25 | +use Doctrine\ODM\MongoDB\DocumentManager; |
23 | 26 |
|
24 | 27 | /** |
25 | 28 | * @author Vincent Amstoutz <[email protected]> |
26 | 29 | */ |
27 | | -final class IriFilter implements FilterInterface, OpenApiParameterFilterInterface, ParameterProviderFilterInterface |
| 30 | +final class IriFilter implements FilterInterface, OpenApiParameterFilterInterface, ParameterProviderFilterInterface, ManagerRegistryAwareInterface |
28 | 31 | { |
29 | 32 | use BackwardCompatibleFilterDescriptionTrait; |
| 33 | + use ManagerRegistryAwareTrait; |
30 | 34 | use OpenApiFilterTrait; |
31 | 35 |
|
32 | 36 | public function apply(Builder $aggregationBuilder, string $resourceClass, ?Operation $operation = null, array &$context = []): void |
33 | 37 | { |
34 | 38 | $parameter = $context['parameter']; |
| 39 | + $property = $parameter->getProperty(); |
35 | 40 | $value = $parameter->getValue(); |
36 | 41 |
|
37 | | - $isIterable = is_iterable($value); |
38 | | - if ($isIterable) { |
39 | | - $ids = array_map(static fn (object $object) => $object->getId(), iterator_to_array($value)); |
40 | | - } else { |
41 | | - $ids = \is_object($value) ? $value->getId() : $value; |
| 42 | + $documentManager = $this->getManagerRegistry()?->getManagerForClass($resourceClass); |
| 43 | + |
| 44 | + if (!$documentManager instanceof DocumentManager) { |
| 45 | + return; |
| 46 | + } |
| 47 | + |
| 48 | + $classMetadata = $documentManager->getClassMetadata($resourceClass); |
| 49 | + |
| 50 | + if (!$classMetadata->hasReference($property)) { |
| 51 | + return; |
| 52 | + } |
| 53 | + |
| 54 | + $method = $classMetadata->isCollectionValuedAssociation($property) ? 'includesReferenceTo' : 'references'; |
| 55 | + |
| 56 | + if (is_iterable($value)) { |
| 57 | + $match = $aggregationBuilder->match(); |
| 58 | + $or = $match->expr(); |
| 59 | + |
| 60 | + foreach ($value as $v) { |
| 61 | + $or->addOr($match->expr()->field($property)->{$method}($v)); |
| 62 | + } |
| 63 | + |
| 64 | + $match->addAnd($or); |
| 65 | + |
| 66 | + return; |
42 | 67 | } |
43 | 68 |
|
44 | 69 | $aggregationBuilder |
45 | 70 | ->match() |
46 | | - ->field('id') |
47 | | - ->{$isIterable ? 'in' : 'equals'}($ids); |
| 71 | + ->field($property) |
| 72 | + ->{$method}($value); |
48 | 73 | } |
49 | 74 |
|
50 | 75 | public static function getParameterProvider(): string |
|
0 commit comments