1818use ApiPlatform \Doctrine \Odm \State \Options as ODMOptions ;
1919use ApiPlatform \Doctrine \Orm \State \Options ;
2020use ApiPlatform \Metadata \FilterInterface ;
21+ use ApiPlatform \Metadata \Parameter ;
22+ use ApiPlatform \Metadata \Parameters ;
23+ use ApiPlatform \Metadata \QueryParameterInterface ;
2124use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
2225use ApiPlatform \Metadata \ResourceClassResolverInterface ;
2326use ApiPlatform \Serializer \CacheableSupportsMethodInterface ;
@@ -97,8 +100,10 @@ public function normalize(mixed $object, ?string $format = null, array $context
97100 }
98101 $ resourceClass = $ this ->resourceClassResolver ->getResourceClass ($ object , $ context ['resource_class ' ]);
99102 $ operation = $ context ['operation ' ] ?? $ this ->resourceMetadataCollectionFactory ->create ($ resourceClass )->getOperation ($ context ['operation_name ' ] ?? null );
103+
104+ $ parameters = $ operation ->getParameters ();
100105 $ resourceFilters = $ operation ->getFilters ();
101- if (!$ resourceFilters ) {
106+ if (!$ resourceFilters && ! $ parameters ) {
102107 return $ data ;
103108 }
104109
@@ -123,8 +128,8 @@ public function normalize(mixed $object, ?string $format = null, array $context
123128 }
124129 }
125130
126- if ($ currentFilters ) {
127- $ data ['hydra:search ' ] = $ this ->getSearch ($ resourceClass , $ requestParts , $ currentFilters );
131+ if ($ currentFilters || ( $ parameters && \count ( $ parameters )) ) {
132+ $ data ['hydra:search ' ] = $ this ->getSearch ($ resourceClass , $ requestParts , $ currentFilters, $ parameters );
128133 }
129134
130135 return $ data ;
@@ -144,8 +149,9 @@ public function setNormalizer(NormalizerInterface $normalizer): void
144149 * Returns the content of the Hydra search property.
145150 *
146151 * @param LegacyFilterInterface[]|FilterInterface[] $filters
152+ * @param array<string, Parameter> $parameters
147153 */
148- private function getSearch (string $ resourceClass , array $ parts , array $ filters ): array
154+ private function getSearch (string $ resourceClass , array $ parts , array $ filters, array | Parameters | null $ parameters ): array
149155 {
150156 $ variables = [];
151157 $ mapping = [];
@@ -156,6 +162,45 @@ private function getSearch(string $resourceClass, array $parts, array $filters):
156162 }
157163 }
158164
165+ foreach ($ parameters ?? [] as $ key => $ parameter ) {
166+ // Each IriTemplateMapping maps a variable used in the template to a property
167+ if (!$ parameter instanceof QueryParameterInterface) {
168+ continue ;
169+ }
170+
171+ if (!($ property = $ parameter ->getProperty ()) && ($ filterId = $ parameter ->getFilter ()) && ($ filter = $ this ->getFilter ($ filterId ))) {
172+ foreach ($ filter ->getDescription ($ resourceClass ) as $ variable => $ description ) {
173+ // This is a practice induced by PHP and is not necessary when implementing URI template
174+ if (str_ends_with ((string ) $ variable , '[] ' )) {
175+ continue ;
176+ }
177+
178+ // :property is a pattern allowed when defining parameters
179+ $ k = str_replace (':property ' , $ description ['property ' ], $ key );
180+ $ variable = str_replace ($ description ['property ' ], $ k , $ variable );
181+ $ variables [] = $ variable ;
182+ $ m = ['@type ' => 'IriTemplateMapping ' , 'variable ' => $ variable , 'property ' => $ description ['property ' ], 'required ' => $ description ['required ' ]];
183+ if (null !== ($ required = $ parameter ->getRequired ())) {
184+ $ m ['required ' ] = $ required ;
185+ }
186+ $ mapping [] = $ m ;
187+ }
188+
189+ continue ;
190+ }
191+
192+ if (!$ property ) {
193+ continue ;
194+ }
195+
196+ $ m = ['@type ' => 'IriTemplateMapping ' , 'variable ' => $ key , 'property ' => $ property ];
197+ $ variables [] = $ key ;
198+ if (null !== ($ required = $ parameter ->getRequired ())) {
199+ $ m ['required ' ] = $ required ;
200+ }
201+ $ mapping [] = $ m ;
202+ }
203+
159204 return ['@type ' => 'hydra:IriTemplate ' , 'hydra:template ' => sprintf ('%s{?%s} ' , $ parts ['path ' ], implode (', ' , $ variables )), 'hydra:variableRepresentation ' => 'BasicRepresentation ' , 'hydra:mapping ' => $ mapping ];
160205 }
161206
0 commit comments