1010use Neos \Flow \ObjectManagement \Proxy \ProxyInterface ;
1111use Neos \Flow \Reflection \ClassReflection ;
1212use Neos \Flow \Reflection \MethodReflection ;
13+ use Neos \Flow \Reflection \ParameterReflection ;
1314use Neos \Flow \Reflection \ReflectionService ;
1415use Neos \Utility \Arrays ;
1516use Psr \Http \Message \UriFactoryInterface ;
2324use Sitegeist \SchemeOnYou \Domain \Path \OpenApiPathItem ;
2425use Sitegeist \SchemeOnYou \Domain \Path \OpenApiRequestBody ;
2526use Sitegeist \SchemeOnYou \Domain \Path \OpenApiResponses ;
27+ use Sitegeist \SchemeOnYou \Domain \Path \ParameterLocation ;
2628use Sitegeist \SchemeOnYou \Domain \Path \PathDefinition ;
2729use Sitegeist \SchemeOnYou \Domain \Schema \IsSupportedInSchema ;
2830use Sitegeist \SchemeOnYou \Domain \Schema \OpenApiSchemaCollection ;
@@ -99,7 +101,7 @@ public function createOpenApiDocumentFromNameAndClassNamePattern(
99101 }
100102 }
101103 }
102- $ paths = $ paths ->merge ($ this ->createPathsFromPathAndMethodReflection ($ classReflection , $ methodReflection ));
104+ $ paths = $ paths ->merge ($ this ->createPathsFromClassAndMethodReflection ($ classReflection , $ methodReflection ));
103105 }
104106
105107 $ requiredSchemaClasses = $ this ->addConstructorArgumentTypesToRequiredSchemaClasses ($ requiredSchemaClasses );
@@ -121,7 +123,7 @@ public function createOpenApiDocumentFromNameAndClassNamePattern(
121123 );
122124 }
123125
124- private function createPathsFromPathAndMethodReflection (ClassReflection $ classReflection , MethodReflection $ methodReflection ): OpenApiPathCollection
126+ private function createPathsFromClassAndMethodReflection (ClassReflection $ classReflection , MethodReflection $ methodReflection ): OpenApiPathCollection
125127 {
126128 /**
127129 * @var OpenApiPathItem[] $paths
@@ -159,27 +161,14 @@ private function createPathsFromPathAndMethodReflection(ClassReflection $classRe
159161 $ controller = substr ($ controllerName , 0 , -10 );
160162 $ action = substr ($ methodName , 0 , -6 );
161163
162- $ resolveContext = new ResolveContext (
163- $ this ->uriFactory ->createUri ('http://localhost ' ),
164- [
165- '@package ' => $ controllerPackageKey ,
166- '@subpackage ' => $ subPackage ,
167- '@controller ' => $ controller ,
168- '@action ' => $ action ,
169- ],
170- false ,
171- '' ,
172- RouteParameters::createEmpty ()->withParameter ('requestUriHost ' , 'localhost ' )
173- );
174-
175164 $ requestBody = null ;
176165 $ parameters = [];
177- foreach ($ methodReflection ->getParameters () as $ reflectionParameter ) {
178- $ parameterProcessed = false ;
166+ $ bodyParameterIsAlreadyProcessed = false ;
179167
168+ foreach ($ methodReflection ->getParameters () as $ reflectionParameter ) {
180169 if ($ bodyAttributes = $ reflectionParameter ->getAttributes (RequestBody::class)) {
181170 foreach ($ bodyAttributes as $ attribute ) {
182- if ($ parameterProcessed ) {
171+ if ($ bodyParameterIsAlreadyProcessed ) {
183172 throw new \DomainException (
184173 'Method parameter ' . $ methodReflection ->getDeclaringClass ()->name
185174 . ':: ' . $ methodReflection ->getName () . ':: ' . $ reflectionParameter ->name
@@ -194,26 +183,42 @@ private function createPathsFromPathAndMethodReflection(ClassReflection $classRe
194183 );
195184 }
196185 $ requestBody = OpenApiRequestBody::fromReflectionParameter ($ reflectionParameter );
197- $ parameterProcessed = true ;
198- }
199- } elseif ($ parameterAttributes = $ reflectionParameter ->getAttributes (Parameter::class)) {
200- foreach ($ parameterAttributes as $ attribute ) {
201- if ($ parameterProcessed ) {
202- throw new \DomainException (
203- 'Method parameter ' . $ methodReflection ->getDeclaringClass ()->name
204- . ':: ' . $ methodReflection ->getName () . ':: ' . $ reflectionParameter ->name
205- . ' must be attributed as either OpenAPI Parameter or RequestBody '
206- . ' and was already attributed '
207- );
208- }
209- $ parameters [] = OpenApiParameter::fromReflectionParameter ($ reflectionParameter );
210- $ parameterProcessed = true ;
186+ $ bodyParameterIsAlreadyProcessed = true ;
211187 }
212188 } else {
213189 $ parameters [] = OpenApiParameter::fromReflectionParameter ($ reflectionParameter );
214190 }
215191 }
216192
193+ // add fake string parameters for the LOCATION_PATH parameters
194+ $ additionalRouteValues = array_reduce (
195+ $ parameters ,
196+ function (array $ carry , OpenApiParameter $ parameter ) {
197+ if ($ parameter ->in === ParameterLocation::LOCATION_PATH ) {
198+ $ carry [$ parameter ->name ] = "string " ;
199+ }
200+ return $ carry ;
201+ },
202+ []
203+ );
204+
205+ // we try to route the parameter
206+ $ resolveContext = new ResolveContext (
207+ $ this ->uriFactory ->createUri ('http://localhost ' ),
208+ array_merge (
209+ [
210+ '@package ' => $ controllerPackageKey ,
211+ '@subpackage ' => $ subPackage ,
212+ '@controller ' => $ controller ,
213+ '@action ' => $ action ,
214+ ],
215+ $ additionalRouteValues
216+ ),
217+ false ,
218+ '' ,
219+ RouteParameters::createEmpty ()->withParameter ('requestUriHost ' , 'localhost ' )
220+ );
221+
217222 foreach ($ this ->router ->getRoutes () as $ route ) {
218223 if ($ route ->resolves ($ resolveContext )) {
219224 $ path = str_replace (
@@ -233,8 +238,6 @@ private function createPathsFromPathAndMethodReflection(ClassReflection $classRe
233238 );
234239 }
235240 }
236- // only the first matching route is needed so we can break the loop here
237- break ;
238241 }
239242 }
240243
0 commit comments