@@ -64,15 +64,35 @@ public function __construct(
6464 ) {
6565 }
6666
67- public function toArray (bool $ isParameter = false ): array |stdClass {
68- if ($ isParameter && ($ this ->type === 'object ' || $ this ->ref !== null || $ this ->anyOf !== null || $ this ->allOf !== null )) {
67+ /**
68+ * @param array<string, array<string, mixed>> $schemas
69+ */
70+ private function isParameterSerializable (array $ schemas , ?string $ type , ?bool $ nullable , ?string $ ref , ?array $ anyOf , ?array $ allOf ): bool {
71+ if ($ ref !== null ) {
72+ $ prefix = '#/components/schemas/ ' ;
73+ if (str_starts_with ($ ref , $ prefix ) && ($ schema = $ schemas [substr ($ ref , strlen ($ prefix ))] ?? null ) !== null ) {
74+ return $ this ->isParameterSerializable ($ schemas , $ schema ['type ' ] ?? null , $ schema ['nullable ' ] ?? null , $ schema ['ref ' ] ?? null , $ schema ['anyOf ' ] ?? null , $ schema ['allOf ' ] ?? null );
75+ }
76+
77+ return false ;
78+ }
79+
80+ // https://github.com/OAI/OpenAPI-Specification/issues/1368#issuecomment-354037150
81+ return $ type !== 'object ' && $ anyOf === null && ($ allOf === null || (($ nullable ?? false ) && count ($ allOf ) === 1 ));
82+ }
83+
84+ /**
85+ * @param array<string, array<string, mixed>> $schemas
86+ */
87+ public function toArray (array $ schemas , bool $ isParameter = false ): array |stdClass {
88+ if ($ isParameter && !$ this ->isParameterSerializable ($ schemas , $ this ->type , $ this ->nullable , $ this ->ref , $ this ->anyOf , $ this ->allOf )) {
6989 Logger::warning ($ this ->context , 'Complex types can not be part of query or URL parameters. Falling back to string due to undefined serialization! ' );
7090 return (new OpenApiType (
7191 context: $ this ->context ,
7292 type: 'string ' ,
7393 nullable: $ this ->nullable ,
7494 description: $ this ->description ,
75- ))->toArray ($ isParameter );
95+ ))->toArray ($ schemas , $ isParameter );
7696 }
7797
7898 $ values = [];
@@ -101,7 +121,7 @@ public function toArray(bool $isParameter = false): array|stdClass {
101121 $ values ['description ' ] = Helpers::cleanDocComment ($ this ->description );
102122 }
103123 if ($ this ->items instanceof \OpenAPIExtractor \OpenApiType) {
104- $ values ['items ' ] = $ this ->items ->toArray ();
124+ $ values ['items ' ] = $ this ->items ->toArray ($ schemas );
105125 }
106126 if ($ this ->minLength !== null ) {
107127 $ values ['minLength ' ] = $ this ->minLength ;
@@ -126,24 +146,24 @@ public function toArray(bool $isParameter = false): array|stdClass {
126146 }
127147 if ($ this ->properties !== null && $ this ->properties !== []) {
128148 $ values ['properties ' ] = array_combine (array_keys ($ this ->properties ),
129- array_map (static fn (OpenApiType $ property ): array |\stdClass => $ property ->toArray (), array_values ($ this ->properties )),
149+ array_map (static fn (OpenApiType $ property ): array |\stdClass => $ property ->toArray ($ schemas ), array_values ($ this ->properties )),
130150 );
131151 }
132152 if ($ this ->additionalProperties !== null ) {
133153 if ($ this ->additionalProperties instanceof OpenApiType) {
134- $ values ['additionalProperties ' ] = $ this ->additionalProperties ->toArray ();
154+ $ values ['additionalProperties ' ] = $ this ->additionalProperties ->toArray ($ schemas );
135155 } else {
136156 $ values ['additionalProperties ' ] = $ this ->additionalProperties ;
137157 }
138158 }
139159 if ($ this ->oneOf !== null ) {
140- $ values ['oneOf ' ] = array_map (fn (OpenApiType $ type ): array |\stdClass => $ type ->toArray (), $ this ->oneOf );
160+ $ values ['oneOf ' ] = array_map (fn (OpenApiType $ type ): array |\stdClass => $ type ->toArray ($ schemas ), $ this ->oneOf );
141161 }
142162 if ($ this ->anyOf !== null ) {
143- $ values ['anyOf ' ] = array_map (fn (OpenApiType $ type ): array |\stdClass => $ type ->toArray (), $ this ->anyOf );
163+ $ values ['anyOf ' ] = array_map (fn (OpenApiType $ type ): array |\stdClass => $ type ->toArray ($ schemas ), $ this ->anyOf );
144164 }
145165 if ($ this ->allOf !== null ) {
146- $ values ['allOf ' ] = array_map (fn (OpenApiType $ type ): array |\stdClass => $ type ->toArray (), $ this ->allOf );
166+ $ values ['allOf ' ] = array_map (fn (OpenApiType $ type ): array |\stdClass => $ type ->toArray ($ schemas ), $ this ->allOf );
147167 }
148168
149169 return $ values !== [] ? $ values : new stdClass ();
0 commit comments