@@ -331,12 +331,26 @@ private function collectPaths(ApiResource $resource, ResourceMetadataCollection
331331 }
332332 }
333333
334+ $ entityClass = $ this ->getFilterClass ($ operation );
334335 $ openapiParameters = $ openapiOperation ->getParameters ();
335336 foreach ($ operation ->getParameters () ?? [] as $ key => $ p ) {
336337 if (false === $ p ->getOpenApi ()) {
337338 continue ;
338339 }
339340
341+ if (($ f = $ p ->getFilter ()) && \is_string ($ f ) && $ this ->filterLocator ->has ($ f )) {
342+ $ filter = $ this ->filterLocator ->get ($ f );
343+ foreach ($ filter ->getDescription ($ entityClass ) as $ name => $ description ) {
344+ if ($ prop = $ p ->getProperty ()) {
345+ $ name = str_replace ($ prop , $ key , $ name );
346+ }
347+
348+ $ openapiParameters [] = $ this ->getFilterParameter ($ name , $ description , $ operation ->getShortName (), $ f );
349+ }
350+
351+ continue ;
352+ }
353+
340354 $ in = $ p instanceof HeaderParameterInterface ? 'header ' : 'query ' ;
341355 $ parameter = new Parameter ($ key , $ in , $ p ->getDescription () ?? "$ resourceShortName $ key " , $ p ->getRequired () ?? false , false , false , $ p ->getSchema () ?? ['type ' => 'string ' ]);
342356
@@ -654,92 +668,102 @@ private function getLinks(ResourceMetadataCollection $resourceMetadataCollection
654668 private function getFiltersParameters (CollectionOperationInterface |HttpOperation $ operation ): array
655669 {
656670 $ parameters = [];
657-
658671 $ resourceFilters = $ operation ->getFilters ();
672+ $ entityClass = $ this ->getFilterClass ($ operation );
673+
659674 foreach ($ resourceFilters ?? [] as $ filterId ) {
660675 if (!$ this ->filterLocator ->has ($ filterId )) {
661676 continue ;
662677 }
663678
664679 $ filter = $ this ->filterLocator ->get ($ filterId );
665- $ entityClass = $ operation ->getClass ();
666- if ($ options = $ operation ->getStateOptions ()) {
667- if ($ options instanceof DoctrineOptions && $ options ->getEntityClass ()) {
668- $ entityClass = $ options ->getEntityClass ();
669- }
670-
671- if ($ options instanceof DoctrineODMOptions && $ options ->getDocumentClass ()) {
672- $ entityClass = $ options ->getDocumentClass ();
673- }
680+ foreach ($ filter ->getDescription ($ entityClass ) as $ name => $ description ) {
681+ $ parameters [] = $ this ->getFilterParameter ($ name , $ description , $ operation ->getShortName (), $ filterId );
674682 }
683+ }
675684
676- foreach ($ filter ->getDescription ($ entityClass ) as $ name => $ data ) {
677- if (isset ($ data ['swagger ' ])) {
678- trigger_deprecation ('api-platform/core ' , '4.0 ' , \sprintf ('Using the "swagger" field of the %s::getDescription() (%s) is deprecated. ' , $ filter ::class, $ operation ->getShortName ()));
679- }
685+ return $ parameters ;
686+ }
680687
681- if (!isset ($ data ['openapi ' ]) || $ data ['openapi ' ] instanceof Parameter) {
682- $ schema = $ data ['schema ' ] ?? [];
688+ private function getFilterClass (HttpOperation $ operation ): ?string
689+ {
690+ $ entityClass = $ operation ->getClass ();
691+ if ($ options = $ operation ->getStateOptions ()) {
692+ if ($ options instanceof DoctrineOptions && $ options ->getEntityClass ()) {
693+ return $ options ->getEntityClass ();
694+ }
683695
684- if (isset ($ data ['type ' ]) && \in_array ($ data ['type ' ] ?? null , Type::$ builtinTypes , true ) && !isset ($ schema ['type ' ])) {
685- $ schema += $ this ->jsonSchemaTypeFactory ? $ this ->jsonSchemaTypeFactory ->getType (new Type ($ data ['type ' ], false , null , $ data ['is_collection ' ] ?? false )) : $ this ->getType (new Type ($ data ['type ' ], false , null , $ data ['is_collection ' ] ?? false ));
686- }
696+ if ($ options instanceof DoctrineODMOptions && $ options ->getDocumentClass ()) {
697+ return $ options ->getDocumentClass ();
698+ }
699+ }
687700
688- if (!isset ($ schema ['type ' ])) {
689- $ schema ['type ' ] = 'string ' ;
690- }
701+ return $ entityClass ;
702+ }
691703
692- $ style = ' array ' === ( $ schema [ ' type ' ] ?? null ) && \in_array (
693- $ data [ ' type ' ],
694- [Type:: BUILTIN_TYPE_ARRAY , Type:: BUILTIN_TYPE_OBJECT ],
695- true
696- ) ? ' deepObject ' : ' form ' ;
704+ private function getFilterParameter ( string $ name , array $ description , string $ shortName , string $ filter ): Parameter
705+ {
706+ if ( isset ( $ description [ ' swagger ' ])) {
707+ trigger_deprecation ( ' api-platform/core ' , ' 4.0 ' , \sprintf ( ' Using the "swagger" field of the %s::getDescription() (%s) is deprecated. ' , $ filter , $ shortName ));
708+ }
697709
698- $ parameter = isset ($ data ['openapi ' ]) && $ data ['openapi ' ] instanceof Parameter ? $ data ['openapi ' ] : new Parameter (in: 'query ' , name: $ name , style: $ style , explode: $ data ['is_collection ' ] ?? false );
710+ if (!isset ($ description ['openapi ' ]) || $ description ['openapi ' ] instanceof Parameter) {
711+ $ schema = $ description ['schema ' ] ?? [];
699712
700- if ('' === $ parameter -> getDescription ( ) && ($ description = $ data [ ' description ' ] ?? '' )) {
701- $ parameter = $ parameter -> withDescription ( $ description );
702- }
713+ if (isset ( $ description [ ' type ' ] ) && \in_array ($ description[ ' type ' ], Type:: $ builtinTypes , true ) && ! isset ( $ schema [ ' type ' ] )) {
714+ $ schema += $ this -> jsonSchemaTypeFactory ? $ this -> jsonSchemaTypeFactory -> getType ( new Type ( $ description [ ' type ' ], false , null , $ description [ ' is_collection ' ] ?? false )) : $ this -> getType ( new Type ( $ description[ ' type ' ], false , null , $ description [ ' is_collection ' ] ?? false ) );
715+ }
703716
704- if (false === $ parameter -> getRequired () && false !== ( $ required = $ data [ ' required ' ] ?? false )) {
705- $ parameter = $ parameter -> withRequired ( $ required ) ;
706- }
717+ if (! isset ( $ schema [ ' type ' ] )) {
718+ $ schema [ ' type ' ] = ' string ' ;
719+ }
707720
708- $ parameters [] = $ parameter ->withSchema ($ schema );
709- continue ;
710- }
721+ $ style = 'array ' === ($ schema ['type ' ] ?? null ) && \in_array (
722+ $ description ['type ' ],
723+ [Type::BUILTIN_TYPE_ARRAY , Type::BUILTIN_TYPE_OBJECT ],
724+ true
725+ ) ? 'deepObject ' : 'form ' ;
711726
712- trigger_deprecation ('api-platform/core ' , '4.0 ' , \sprintf ('Not using "%s" on the "openapi" field of the %s::getDescription() (%s) is deprecated. ' , Parameter::class, $ filter ::class, $ operation ->getShortName ()));
713- if ($ this ->jsonSchemaTypeFactory ) {
714- $ schema = $ data ['schema ' ] ?? (\in_array ($ data ['type ' ], Type::$ builtinTypes , true ) ? $ this ->jsonSchemaTypeFactory ->getType (new Type ($ data ['type ' ], false , null , $ data ['is_collection ' ] ?? false ), 'openapi ' ) : ['type ' => 'string ' ]);
715- } else {
716- $ schema = $ data ['schema ' ] ?? (\in_array ($ data ['type ' ], Type::$ builtinTypes , true ) ? $ this ->getType (new Type ($ data ['type ' ], false , null , $ data ['is_collection ' ] ?? false )) : ['type ' => 'string ' ]);
717- }
727+ $ parameter = isset ($ description ['openapi ' ]) && $ description ['openapi ' ] instanceof Parameter ? $ description ['openapi ' ] : new Parameter (in: 'query ' , name: $ name , style: $ style , explode: $ description ['is_collection ' ] ?? false );
718728
719- $ parameters [] = new Parameter (
720- $ name ,
721- 'query ' ,
722- $ data ['description ' ] ?? '' ,
723- $ data ['required ' ] ?? false ,
724- $ data ['openapi ' ]['deprecated ' ] ?? false ,
725- $ data ['openapi ' ]['allowEmptyValue ' ] ?? true ,
726- $ schema ,
727- 'array ' === $ schema ['type ' ] && \in_array (
728- $ data ['type ' ],
729- [Type::BUILTIN_TYPE_ARRAY , Type::BUILTIN_TYPE_OBJECT ],
730- true
731- ) ? 'deepObject ' : 'form ' ,
732- $ data ['openapi ' ]['explode ' ] ?? ('array ' === $ schema ['type ' ]),
733- $ data ['openapi ' ]['allowReserved ' ] ?? false ,
734- $ data ['openapi ' ]['example ' ] ?? null ,
735- isset (
736- $ data ['openapi ' ]['examples ' ]
737- ) ? new \ArrayObject ($ data ['openapi ' ]['examples ' ]) : null
738- );
729+ if ('' === $ parameter ->getDescription () && ($ str = $ description ['description ' ] ?? '' )) {
730+ $ parameter = $ parameter ->withDescription ($ str );
731+ }
732+
733+ if (false === $ parameter ->getRequired () && false !== ($ required = $ description ['required ' ] ?? false )) {
734+ $ parameter = $ parameter ->withRequired ($ required );
739735 }
736+
737+ return $ parameter ->withSchema ($ schema );
740738 }
741739
742- return $ parameters ;
740+ trigger_deprecation ('api-platform/core ' , '4.0 ' , \sprintf ('Not using "%s" on the "openapi" field of the %s::getDescription() (%s) is deprecated. ' , Parameter::class, $ filter , $ shortName ));
741+ if ($ this ->jsonSchemaTypeFactory ) {
742+ $ schema = $ description ['schema ' ] ?? (\in_array ($ description ['type ' ], Type::$ builtinTypes , true ) ? $ this ->jsonSchemaTypeFactory ->getType (new Type ($ description ['type ' ], false , null , $ description ['is_collection ' ] ?? false ), 'openapi ' ) : ['type ' => 'string ' ]);
743+ } else {
744+ $ schema = $ description ['schema ' ] ?? (\in_array ($ description ['type ' ], Type::$ builtinTypes , true ) ? $ this ->getType (new Type ($ description ['type ' ], false , null , $ description ['is_collection ' ] ?? false )) : ['type ' => 'string ' ]);
745+ }
746+
747+ return new Parameter (
748+ $ name ,
749+ 'query ' ,
750+ $ description ['description ' ] ?? '' ,
751+ $ description ['required ' ] ?? false ,
752+ $ description ['openapi ' ]['deprecated ' ] ?? false ,
753+ $ description ['openapi ' ]['allowEmptyValue ' ] ?? true ,
754+ $ schema ,
755+ 'array ' === $ schema ['type ' ] && \in_array (
756+ $ description ['type ' ],
757+ [Type::BUILTIN_TYPE_ARRAY , Type::BUILTIN_TYPE_OBJECT ],
758+ true
759+ ) ? 'deepObject ' : 'form ' ,
760+ $ description ['openapi ' ]['explode ' ] ?? ('array ' === $ schema ['type ' ]),
761+ $ description ['openapi ' ]['allowReserved ' ] ?? false ,
762+ $ description ['openapi ' ]['example ' ] ?? null ,
763+ isset (
764+ $ description ['openapi ' ]['examples ' ]
765+ ) ? new \ArrayObject ($ description ['openapi ' ]['examples ' ]) : null
766+ );
743767 }
744768
745769 private function getPaginationParameters (CollectionOperationInterface |HttpOperation $ operation ): array
0 commit comments