13
13
14
14
namespace ApiPlatform \Doctrine \Orm \Extension ;
15
15
16
+ use ApiPlatform \Doctrine \Common \Filter \ManagerRegistryAwareInterface ;
16
17
use ApiPlatform \Doctrine \Common \ParameterValueExtractorTrait ;
18
+ use ApiPlatform \Doctrine \Orm \Filter \AbstractFilter ;
17
19
use ApiPlatform \Doctrine \Orm \Filter \FilterInterface ;
18
20
use ApiPlatform \Doctrine \Orm \Util \QueryNameGeneratorInterface ;
19
21
use ApiPlatform \Metadata \Exception \InvalidArgumentException ;
20
22
use ApiPlatform \Metadata \Operation ;
21
23
use ApiPlatform \State \ParameterNotFound ;
22
24
use Doctrine \ORM \QueryBuilder ;
25
+ use Psr \Container \ContainerExceptionInterface ;
23
26
use Psr \Container \ContainerInterface ;
27
+ use Psr \Container \NotFoundExceptionInterface ;
28
+ use Symfony \Bridge \Doctrine \ManagerRegistry ;
24
29
25
30
/**
26
31
* Reads operation parameters and execute its filter.
@@ -31,17 +36,22 @@ final class ParameterExtension implements QueryCollectionExtensionInterface, Que
31
36
{
32
37
use ParameterValueExtractorTrait;
33
38
34
- public function __construct (private readonly ContainerInterface $ filterLocator )
35
- {
39
+ public function __construct (
40
+ private readonly ContainerInterface $ filterLocator ,
41
+ private readonly ?ManagerRegistry $ managerRegistry = null ,
42
+ ) {
36
43
}
37
44
38
45
/**
39
46
* @param array<string, mixed> $context
47
+ *
48
+ * @throws ContainerExceptionInterface
49
+ * @throws NotFoundExceptionInterface
40
50
*/
41
51
private function applyFilter (QueryBuilder $ queryBuilder , QueryNameGeneratorInterface $ queryNameGenerator , string $ resourceClass , ?Operation $ operation = null , array $ context = []): void
42
52
{
43
53
foreach ($ operation ?->getParameters() ?? [] as $ parameter ) {
44
- if (! ($ v = $ parameter ->getValue ()) || $ v instanceof ParameterNotFound) {
54
+ if (null === ($ v = $ parameter ->getValue ()) || $ v instanceof ParameterNotFound) {
45
55
continue ;
46
56
}
47
57
@@ -50,12 +60,31 @@ private function applyFilter(QueryBuilder $queryBuilder, QueryNameGeneratorInter
50
60
continue ;
51
61
}
52
62
53
- $ filter = $ this ->filterLocator ->has ($ filterId ) ? $ this ->filterLocator ->get ($ filterId ) : null ;
54
- if (!$ filter instanceof FilterInterface) {
63
+ $ filter = match (true ) {
64
+ $ filterId instanceof FilterInterface => $ filterId ,
65
+ \is_string ($ filterId ) && $ this ->filterLocator ->has ($ filterId ) => $ this ->filterLocator ->get ($ filterId ),
66
+ default => null ,
67
+ };
68
+
69
+ if (!($ filter instanceof FilterInterface)) {
55
70
throw new InvalidArgumentException (\sprintf ('Could not find filter "%s" for parameter "%s" in operation "%s" for resource "%s". ' , $ filterId , $ parameter ->getKey (), $ operation ?->getShortName(), $ resourceClass ));
56
71
}
57
72
58
- $ filter ->apply ($ queryBuilder , $ queryNameGenerator , $ resourceClass , $ operation , ['filters ' => $ values , 'parameter ' => $ parameter ] + $ context );
73
+ if ($ filter instanceof ManagerRegistryAwareInterface && !$ filter ->hasManagerRegistry ()) {
74
+ $ filter ->setManagerRegistry ($ this ->managerRegistry );
75
+ }
76
+
77
+ if ($ filter instanceof AbstractFilter && !$ filter ->getProperties ()) {
78
+ $ propertyKey = $ parameter ->getProperty () ?? $ parameter ->getKey ();
79
+ $ filterContext = $ parameter ->getFilterContext ();
80
+
81
+ $ properties = \is_array ($ filterContext ) ? $ filterContext : [$ propertyKey => $ filterContext ];
82
+ $ filter ->setProperties ($ properties );
83
+ }
84
+
85
+ $ filter ->apply ($ queryBuilder , $ queryNameGenerator , $ resourceClass , $ operation ,
86
+ ['filters ' => $ values , 'parameter ' => $ parameter ] + $ context
87
+ );
59
88
}
60
89
}
61
90
0 commit comments