1313
1414namespace ApiPlatform \Doctrine \Orm \Extension ;
1515
16+ use ApiPlatform \Doctrine \Common \Filter \ManagerRegistryAwareInterface ;
1617use ApiPlatform \Doctrine \Common \ParameterValueExtractorTrait ;
18+ use ApiPlatform \Doctrine \Orm \Filter \AbstractFilter ;
1719use ApiPlatform \Doctrine \Orm \Filter \FilterInterface ;
1820use ApiPlatform \Doctrine \Orm \Util \QueryNameGeneratorInterface ;
1921use ApiPlatform \Metadata \Exception \InvalidArgumentException ;
2022use ApiPlatform \Metadata \Operation ;
2123use ApiPlatform \State \ParameterNotFound ;
2224use Doctrine \ORM \QueryBuilder ;
25+ use Psr \Container \ContainerExceptionInterface ;
2326use Psr \Container \ContainerInterface ;
27+ use Psr \Container \NotFoundExceptionInterface ;
28+ use Symfony \Bridge \Doctrine \ManagerRegistry ;
2429
2530/**
2631 * Reads operation parameters and execute its filter.
@@ -31,17 +36,22 @@ final class ParameterExtension implements QueryCollectionExtensionInterface, Que
3136{
3237 use ParameterValueExtractorTrait;
3338
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+ ) {
3643 }
3744
3845 /**
3946 * @param array<string, mixed> $context
47+ *
48+ * @throws ContainerExceptionInterface
49+ * @throws NotFoundExceptionInterface
4050 */
4151 private function applyFilter (QueryBuilder $ queryBuilder , QueryNameGeneratorInterface $ queryNameGenerator , string $ resourceClass , ?Operation $ operation = null , array $ context = []): void
4252 {
4353 foreach ($ operation ?->getParameters() ?? [] as $ parameter ) {
44- if (! ($ v = $ parameter ->getValue ()) || $ v instanceof ParameterNotFound) {
54+ if (null === ($ v = $ parameter ->getValue ()) || $ v instanceof ParameterNotFound) {
4555 continue ;
4656 }
4757
@@ -50,12 +60,31 @@ private function applyFilter(QueryBuilder $queryBuilder, QueryNameGeneratorInter
5060 continue ;
5161 }
5262
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)) {
5570 throw new InvalidArgumentException (\sprintf ('Could not find filter "%s" for parameter "%s" in operation "%s" for resource "%s". ' , $ filterId , $ parameter ->getKey (), $ operation ?->getShortName(), $ resourceClass ));
5671 }
5772
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+ );
5988 }
6089 }
6190
0 commit comments