diff --git a/modules/openapi-generator/src/main/resources/php/ObjectSerializer.mustache b/modules/openapi-generator/src/main/resources/php/ObjectSerializer.mustache index 61b146fd9d9..350c377dc4c 100644 --- a/modules/openapi-generator/src/main/resources/php/ObjectSerializer.mustache +++ b/modules/openapi-generator/src/main/resources/php/ObjectSerializer.mustache @@ -149,22 +149,61 @@ class ObjectSerializer } /** - * Take value and turn it into a string suitable for inclusion in - * the query, by imploding comma-separated if it's an object. - * If it's a string, pass through unchanged. It will be url-encoded - * later. + * Take query parameter properties and turn it into an array suitable for + * native http_build_query or GuzzleHttp\Psr7\Query::build. * - * @param string[]|string|\DateTime $object an object to be serialized to a string + * @param mixed $value Parameter value + * @param string $paramName Parameter name + * @param string $openApiType OpenAPIType eg. array or object + * @param string $style Parameter serialization style + * @param bool $explode Parameter explode option * - * @return string the serialized object + * @return array */ - public static function toQueryValue($object) - { - if (is_array($object)) { - return implode(',', $object); - } else { - return self::toString($object); + public static function toQueryValue( + $value, + string $paramName, + string $openApiType = 'string', + string $style = 'form', + bool $explode = true + ): array { + // return empty string + if (empty($value)) return ["{$paramName}" => '']; + + $query = []; + $value = (in_array($openApiType, ['object', 'array'], true)) ? (array)$value : $value; + + // since \GuzzleHttp\Psr7\Query::build fails with nested arrays + // need to flatten array first + $flattenArray = function ($arr, $name, &$result = []) use (&$flattenArray, $style, $explode) { + if (!is_array($arr)) return $arr; + + foreach ($arr as $k => $v) { + $prop = ($style === 'deepObject') ? $prop = "{$name}[{$k}]" : $k; + + if (is_array($v)) { + $flattenArray($v, $prop, $result); + } else { + if ($style !== 'deepObject' && !$explode) { + // push key itself + $result[] = $prop; + } + $result[$prop] = $v; + } + } + return $result; + }; + + $value = $flattenArray($value, $paramName); + + if ($openApiType === 'object' && ($style === 'deepObject' || $explode)) { + return $value; } + + // handle style in serializeCollection + $query[$paramName] = ($explode) ? $value : self::serializeCollection((array)$value, $style); + + return $query; } /** @@ -403,4 +442,24 @@ class ObjectSerializer return $instance; } } + + /** + * Native `http_build_query` wrapper. + * @see https://www.php.net/manual/en/function.http-build-query + * + * @param array|object $data May be an array or object containing properties. + * @param string $numeric_prefix If numeric indices are used in the base array and this parameter is provided, it will be prepended to the numeric index for elements in the base array only. + * @param string|null $arg_separator arg_separator.output is used to separate arguments but may be overridden by specifying this parameter. + * @param int $encoding_type Encoding type. By default, PHP_QUERY_RFC1738. + * + * @return string + */ + public static function buildQuery( + $data, + string $numeric_prefix = '', + ?string $arg_separator = null, + int $encoding_type = \PHP_QUERY_RFC3986 + ): string { + return \GuzzleHttp\Psr7\Query::build($data, $encoding_type); + } } diff --git a/modules/openapi-generator/src/main/resources/php/api.mustache b/modules/openapi-generator/src/main/resources/php/api.mustache index f9c5c041fbb..8d875d39378 100644 --- a/modules/openapi-generator/src/main/resources/php/api.mustache +++ b/modules/openapi-generator/src/main/resources/php/api.mustache @@ -497,31 +497,13 @@ use {{invokerPackage}}\ObjectSerializer; {{#queryParams}} // query params - {{#isExplode}} - if (${{paramName}} !== null) { - {{#style}} - if('form' === '{{style}}' && is_array(${{paramName}})) { - foreach(${{paramName}} as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['{{baseName}}'] = ${{paramName}}; - } - {{/style}} - {{^style}} - $queryParams['{{baseName}}'] = ${{paramName}}; - {{/style}} - } - {{/isExplode}} - {{^isExplode}} - if (is_array(${{paramName}})) { - ${{paramName}} = ObjectSerializer::serializeCollection(${{paramName}}, '{{style}}{{^style}}{{collectionFormat}}{{/style}}', true); - } - if (${{paramName}} !== null) { - $queryParams['{{baseName}}'] = ${{paramName}}; - } - {{/isExplode}} + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + ${{paramName}}, + '{{baseName}}', // param base name + '{{#schema}}{{openApiType}}{{/schema}}', // openApiType + '{{style}}', // style + {{#isExplode}}true{{/isExplode}}{{^isExplode}}false{{/isExplode}} // explode + ) ?? []); {{/queryParams}} {{#headerParams}} @@ -615,7 +597,7 @@ use {{invokerPackage}}\ObjectSerializer; } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -668,7 +650,7 @@ use {{invokerPackage}}\ObjectSerializer; $operationHost = $operationHosts[$this->hostIndex]; {{/servers.0}} - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( '{{httpMethod}}', {{^servers.0}}$this->config->getHost(){{/servers.0}}{{#servers.0}}$operationHost{{/servers.0}} . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/AnotherFakeApi.php b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/AnotherFakeApi.php index 62f9f163e07..3d647a96a1e 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/AnotherFakeApi.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/AnotherFakeApi.php @@ -359,7 +359,7 @@ class AnotherFakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -375,7 +375,7 @@ class AnotherFakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PATCH', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/DefaultApi.php b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/DefaultApi.php index 8d912d914d6..df185c316e0 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/DefaultApi.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/DefaultApi.php @@ -334,7 +334,7 @@ class DefaultApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -350,7 +350,7 @@ class DefaultApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeApi.php b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeApi.php index 4aba5d1907c..027fc1335a6 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeApi.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeApi.php @@ -342,7 +342,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -358,7 +358,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -535,16 +535,13 @@ class FakeApi $multipart = false; // query params - if ($query_1 !== null) { - if('form' === 'form' && is_array($query_1)) { - foreach($query_1 as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['query_1'] = $query_1; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $query_1, + 'query_1', // param base name + 'string', // openApiType + 'form', // style + true // explode + ) ?? []); // header params if ($header_1 !== null) { @@ -591,7 +588,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -607,7 +604,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -846,7 +843,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -862,7 +859,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1101,7 +1098,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1117,7 +1114,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1356,7 +1353,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1372,7 +1369,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1611,7 +1608,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1627,7 +1624,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1872,7 +1869,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1888,7 +1885,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -2088,7 +2085,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -2104,7 +2101,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PUT', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -2304,7 +2301,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -2320,7 +2317,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PUT', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -2490,16 +2487,13 @@ class FakeApi $multipart = false; // query params - if ($query !== null) { - if('form' === 'form' && is_array($query)) { - foreach($query as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['query'] = $query; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $query, + 'query', // param base name + 'string', // openApiType + 'form', // style + true // explode + ) ?? []); @@ -2542,7 +2536,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -2558,7 +2552,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PUT', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -2811,7 +2805,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -2827,7 +2821,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PATCH', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -3223,7 +3217,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -3243,7 +3237,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -3439,49 +3433,37 @@ class FakeApi $multipart = false; // query params - if ($enum_query_string_array !== null) { - if('form' === 'form' && is_array($enum_query_string_array)) { - foreach($enum_query_string_array as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['enum_query_string_array'] = $enum_query_string_array; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $enum_query_string_array, + 'enum_query_string_array', // param base name + 'array', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($enum_query_string !== null) { - if('form' === 'form' && is_array($enum_query_string)) { - foreach($enum_query_string as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['enum_query_string'] = $enum_query_string; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $enum_query_string, + 'enum_query_string', // param base name + 'string', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($enum_query_integer !== null) { - if('form' === 'form' && is_array($enum_query_integer)) { - foreach($enum_query_integer as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['enum_query_integer'] = $enum_query_integer; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $enum_query_integer, + 'enum_query_integer', // param base name + 'integer', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($enum_query_double !== null) { - if('form' === 'form' && is_array($enum_query_double)) { - foreach($enum_query_double as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['enum_query_double'] = $enum_query_double; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $enum_query_double, + 'enum_query_double', // param base name + 'number', // openApiType + 'form', // style + true // explode + ) ?? []); // header params if (is_array($enum_header_string_array)) { @@ -3537,7 +3519,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -3553,7 +3535,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -3775,49 +3757,37 @@ class FakeApi $multipart = false; // query params - if ($required_string_group !== null) { - if('form' === 'form' && is_array($required_string_group)) { - foreach($required_string_group as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['required_string_group'] = $required_string_group; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $required_string_group, + 'required_string_group', // param base name + 'integer', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($required_int64_group !== null) { - if('form' === 'form' && is_array($required_int64_group)) { - foreach($required_int64_group as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['required_int64_group'] = $required_int64_group; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $required_int64_group, + 'required_int64_group', // param base name + 'integer', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($string_group !== null) { - if('form' === 'form' && is_array($string_group)) { - foreach($string_group as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['string_group'] = $string_group; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $string_group, + 'string_group', // param base name + 'integer', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($int64_group !== null) { - if('form' === 'form' && is_array($int64_group)) { - foreach($int64_group as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['int64_group'] = $int64_group; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $int64_group, + 'int64_group', // param base name + 'integer', // openApiType + 'form', // style + true // explode + ) ?? []); // header params if ($required_boolean_group !== null) { @@ -3862,7 +3832,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -3882,7 +3852,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'DELETE', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -4090,7 +4060,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -4106,7 +4076,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -4327,7 +4297,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -4343,7 +4313,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -4562,66 +4532,61 @@ class FakeApi $multipart = false; // query params - if (is_array($pipe)) { - $pipe = ObjectSerializer::serializeCollection($pipe, 'pipeDelimited', true); - } - if ($pipe !== null) { - $queryParams['pipe'] = $pipe; - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $pipe, + 'pipe', // param base name + 'array', // openApiType + 'pipeDelimited', // style + false // explode + ) ?? []); // query params - if (is_array($ioutil)) { - $ioutil = ObjectSerializer::serializeCollection($ioutil, 'form', true); - } - if ($ioutil !== null) { - $queryParams['ioutil'] = $ioutil; - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $ioutil, + 'ioutil', // param base name + 'array', // openApiType + 'form', // style + false // explode + ) ?? []); // query params - if (is_array($http)) { - $http = ObjectSerializer::serializeCollection($http, 'spaceDelimited', true); - } - if ($http !== null) { - $queryParams['http'] = $http; - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $http, + 'http', // param base name + 'array', // openApiType + 'spaceDelimited', // style + false // explode + ) ?? []); // query params - if (is_array($url)) { - $url = ObjectSerializer::serializeCollection($url, 'form', true); - } - if ($url !== null) { - $queryParams['url'] = $url; - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $url, + 'url', // param base name + 'array', // openApiType + 'form', // style + false // explode + ) ?? []); // query params - if ($context !== null) { - if('form' === 'form' && is_array($context)) { - foreach($context as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['context'] = $context; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $context, + 'context', // param base name + 'array', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($language !== null) { - if('form' === 'form' && is_array($language)) { - foreach($language as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['language'] = $language; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $language, + 'language', // param base name + 'object', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($allow_empty !== null) { - if('form' === 'form' && is_array($allow_empty)) { - foreach($allow_empty as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['allowEmpty'] = $allow_empty; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $allow_empty, + 'allowEmpty', // param base name + 'string', // openApiType + 'form', // style + true // explode + ) ?? []); @@ -4658,7 +4623,7 @@ class FakeApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -4674,7 +4639,7 @@ class FakeApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PUT', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeClassnameTags123Api.php b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeClassnameTags123Api.php index 611b7d5bba0..fb19ef71181 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeClassnameTags123Api.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/FakeClassnameTags123Api.php @@ -359,7 +359,7 @@ class FakeClassnameTags123Api } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -380,7 +380,7 @@ class FakeClassnameTags123Api $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PATCH', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/PetApi.php b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/PetApi.php index dd8b59aed77..9d0b8a8d5fd 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/PetApi.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/PetApi.php @@ -334,7 +334,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -360,7 +360,7 @@ class PetApi } $operationHost = $operationHosts[$this->hostIndex]; - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $operationHost . $resourcePath . ($query ? "?{$query}" : ''), @@ -579,7 +579,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -599,7 +599,7 @@ class PetApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'DELETE', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -811,12 +811,13 @@ class PetApi $multipart = false; // query params - if (is_array($status)) { - $status = ObjectSerializer::serializeCollection($status, 'form', true); - } - if ($status !== null) { - $queryParams['status'] = $status; - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $status, + 'status', // param base name + 'array', // openApiType + 'form', // style + false // explode + ) ?? []); @@ -853,7 +854,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -873,7 +874,7 @@ class PetApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1091,12 +1092,13 @@ class PetApi $multipart = false; // query params - if (is_array($tags)) { - $tags = ObjectSerializer::serializeCollection($tags, 'form', true); - } - if ($tags !== null) { - $queryParams['tags'] = $tags; - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $tags, + 'tags', // param base name + 'array', // openApiType + 'form', // style + false // explode + ) ?? []); @@ -1133,7 +1135,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1153,7 +1155,7 @@ class PetApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1408,7 +1410,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1429,7 +1431,7 @@ class PetApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1657,7 +1659,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1683,7 +1685,7 @@ class PetApi } $operationHost = $operationHosts[$this->hostIndex]; - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PUT', $operationHost . $resourcePath . ($query ? "?{$query}" : ''), @@ -1911,7 +1913,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1931,7 +1933,7 @@ class PetApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -2212,7 +2214,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -2232,7 +2234,7 @@ class PetApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -2519,7 +2521,7 @@ class PetApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -2539,7 +2541,7 @@ class PetApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/StoreApi.php b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/StoreApi.php index cb3fc4d2f36..e66104dfe6b 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/StoreApi.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/StoreApi.php @@ -316,7 +316,7 @@ class StoreApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -332,7 +332,7 @@ class StoreApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'DELETE', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -568,7 +568,7 @@ class StoreApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -589,7 +589,7 @@ class StoreApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -851,7 +851,7 @@ class StoreApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -867,7 +867,7 @@ class StoreApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1120,7 +1120,7 @@ class StoreApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1136,7 +1136,7 @@ class StoreApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/UserApi.php b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/UserApi.php index f1e8fbe811f..7fc72214ece 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/Api/UserApi.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/Api/UserApi.php @@ -314,7 +314,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -330,7 +330,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -538,7 +538,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -554,7 +554,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -762,7 +762,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -778,7 +778,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'POST', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -988,7 +988,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1004,7 +1004,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'DELETE', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1259,7 +1259,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1275,7 +1275,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1498,27 +1498,21 @@ class UserApi $multipart = false; // query params - if ($username !== null) { - if('form' === 'form' && is_array($username)) { - foreach($username as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['username'] = $username; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $username, + 'username', // param base name + 'string', // openApiType + 'form', // style + true // explode + ) ?? []); // query params - if ($password !== null) { - if('form' === 'form' && is_array($password)) { - foreach($password as $key => $value) { - $queryParams[$key] = $value; - } - } - else { - $queryParams['password'] = $password; - } - } + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $password, + 'password', // param base name + 'string', // openApiType + 'form', // style + true // explode + ) ?? []); @@ -1555,7 +1549,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1571,7 +1565,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -1762,7 +1756,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -1778,7 +1772,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'GET', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), @@ -2005,7 +1999,7 @@ class UserApi } else { // for HTTP post (form) - $httpBody = \GuzzleHttp\Psr7\Query::build($formParams); + $httpBody = ObjectSerializer::buildQuery($queryParams); } } @@ -2021,7 +2015,7 @@ class UserApi $headers ); - $query = \GuzzleHttp\Psr7\Query::build($queryParams); + $query = ObjectSerializer::buildQuery($queryParams); return new Request( 'PUT', $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), diff --git a/samples/client/petstore/php/OpenAPIClient-php/lib/ObjectSerializer.php b/samples/client/petstore/php/OpenAPIClient-php/lib/ObjectSerializer.php index 9bd27f58062..927998508d9 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/lib/ObjectSerializer.php +++ b/samples/client/petstore/php/OpenAPIClient-php/lib/ObjectSerializer.php @@ -158,22 +158,61 @@ class ObjectSerializer } /** - * Take value and turn it into a string suitable for inclusion in - * the query, by imploding comma-separated if it's an object. - * If it's a string, pass through unchanged. It will be url-encoded - * later. + * Take query parameter properties and turn it into an array suitable for + * native http_build_query or GuzzleHttp\Psr7\Query::build. * - * @param string[]|string|\DateTime $object an object to be serialized to a string + * @param mixed $value Parameter value + * @param string $paramName Parameter name + * @param string $openApiType OpenAPIType eg. array or object + * @param string $style Parameter serialization style + * @param bool $explode Parameter explode option * - * @return string the serialized object + * @return array */ - public static function toQueryValue($object) - { - if (is_array($object)) { - return implode(',', $object); - } else { - return self::toString($object); + public static function toQueryValue( + $value, + string $paramName, + string $openApiType = 'string', + string $style = 'form', + bool $explode = true + ): array { + // return empty string + if (empty($value)) return ["{$paramName}" => '']; + + $query = []; + $value = (in_array($openApiType, ['object', 'array'], true)) ? (array)$value : $value; + + // since \GuzzleHttp\Psr7\Query::build fails with nested arrays + // need to flatten array first + $flattenArray = function ($arr, $name, &$result = []) use (&$flattenArray, $style, $explode) { + if (!is_array($arr)) return $arr; + + foreach ($arr as $k => $v) { + $prop = ($style === 'deepObject') ? $prop = "{$name}[{$k}]" : $k; + + if (is_array($v)) { + $flattenArray($v, $prop, $result); + } else { + if ($style !== 'deepObject' && !$explode) { + // push key itself + $result[] = $prop; + } + $result[$prop] = $v; + } + } + return $result; + }; + + $value = $flattenArray($value, $paramName); + + if ($openApiType === 'object' && ($style === 'deepObject' || $explode)) { + return $value; } + + // handle style in serializeCollection + $query[$paramName] = ($explode) ? $value : self::serializeCollection((array)$value, $style); + + return $query; } /** @@ -412,4 +451,24 @@ class ObjectSerializer return $instance; } } + + /** + * Native `http_build_query` wrapper. + * @see https://www.php.net/manual/en/function.http-build-query + * + * @param array|object $data May be an array or object containing properties. + * @param string $numeric_prefix If numeric indices are used in the base array and this parameter is provided, it will be prepended to the numeric index for elements in the base array only. + * @param string|null $arg_separator arg_separator.output is used to separate arguments but may be overridden by specifying this parameter. + * @param int $encoding_type Encoding type. By default, PHP_QUERY_RFC1738. + * + * @return string + */ + public static function buildQuery( + $data, + string $numeric_prefix = '', + ?string $arg_separator = null, + int $encoding_type = \PHP_QUERY_RFC3986 + ): string { + return \GuzzleHttp\Psr7\Query::build($data, $encoding_type); + } } diff --git a/samples/client/petstore/php/OpenAPIClient-php/tests/ObjectSerializerTest.php b/samples/client/petstore/php/OpenAPIClient-php/tests/ObjectSerializerTest.php index bb919ffaa66..64487202dd1 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/tests/ObjectSerializerTest.php +++ b/samples/client/petstore/php/OpenAPIClient-php/tests/ObjectSerializerTest.php @@ -130,4 +130,208 @@ class ObjectSerializerTest extends TestCase ], ]; } + + /** + * @covers ObjectSerializer::toQueryValue + * @dataProvider provideQueryParams + */ + public function testToQueryValue( + $data, + string $paramName, + string $openApiType, + string $style, + bool $explode, + $expected + ): void { + $value = ObjectSerializer::toQueryValue($data, $paramName, $openApiType, $style, $explode); + $query = ObjectSerializer::buildQuery($value); + $this->assertEquals($expected, $query); + } + + public function provideQueryParams(): array + { + $array = ['blue', 'black', 'brown']; + $object = ['R' => 100, 'G' => 200, 'B' => 150]; + + return [ + // style form + // color= + 'form empty, explode on' => [ + '', 'color', 'string', 'form', true, 'color=', + ], + // color= + 'form empty, explode off' => [ + '', 'color', 'string', 'form', false, 'color=', + ], + // color=blue + 'form string, explode on' => [ + 'blue', 'color', 'string', 'form', true, 'color=blue', + ], + // color=blue + 'form string, explode off' => [ + 'blue', 'color', 'string', 'form', false, 'color=blue', + ], + // color=blue&color=black&color=brown + 'form array, explode on' => [ + $array, 'color', 'array', 'form', true, 'color=blue&color=black&color=brown', + ], + // color=blue&color=black&color=brown + 'form nested array, explode on' => [ + ['foobar' => $array], 'color', 'array', 'form', true, 'color=blue&color=black&color=brown', + ], + // color=blue,black,brown + 'form array, explode off' => [ + $array, 'color', 'array', 'form', false, 'color=blue%2Cblack%2Cbrown', + ], + // color=blue,black,brown + 'form nested array, explode off' => [ + ['foobar' => $array], 'color', 'array', 'form', false, 'color=blue%2Cblack%2Cbrown', + ], + // R=100&G=200&B=150 + 'form object, explode on' => [ + $object, 'color', 'object', 'form', true, 'R=100&G=200&B=150', + ], + // color=R,100,G,200,B,150 + 'form object, explode off' => [ + $object, 'color', 'object', 'form', false, 'color=R%2C100%2CG%2C200%2CB%2C150', + ], + + // SPACE DELIMITED + // color=blue + 'spaceDelimited primitive, explode off' => [ + 'blue', 'color', 'string', 'spaceDelimited', false, 'color=blue', + ], + // color=blue + 'spaceDelimited primitive, explode on' => [ + 'blue', 'color', 'string', 'spaceDelimited', true, 'color=blue', + ], + // color=blue%20black%20brown + 'spaceDelimited array, explode off' => [ + $array, 'color', 'array', 'spaceDelimited', false, 'color=blue%20black%20brown', + ], + // color=blue&color=black&color=brown + 'spaceDelimited array, explode on' => [ + $array, 'color', 'array', 'spaceDelimited', true, 'color=blue&color=black&color=brown', + ], + // color=R%20100%20G%20200%20B%20150 + // swagger editor gives color=R,100,G,200,B,150 + 'spaceDelimited object, explode off' => [ + $object, 'color', 'object', 'spaceDelimited', false, 'color=R%20100%20G%20200%20B%20150', + ], + // R=100&G=200&B=150 + 'spaceDelimited object, explode on' => [ + $object, 'color', 'object', 'spaceDelimited', true, 'R=100&G=200&B=150', + ], + + // PIPE DELIMITED + // color=blue + 'pipeDelimited primitive, explode off' => [ + 'blue', 'color', 'string', 'pipeDelimited', false, 'color=blue', + ], + // color=blue + 'pipeDelimited primitive, explode on' => [ + 'blue', 'color', 'string', 'pipeDelimited', true, 'color=blue', + ], + // color=blue|black|brown + 'pipeDelimited array, explode off' => [ + $array, 'color', 'array', 'pipeDelimited', false, 'color=blue%7Cblack%7Cbrown', + ], + // color=blue&color=black&color=brown + 'pipeDelimited array, explode on' => [ + $array, 'color', 'array', 'pipeDelimited', true, 'color=blue&color=black&color=brown', + ], + // color=R|100|G|200|B|150 + // swagger editor gives color=R,100,G,200,B,150 + 'pipeDelimited object, explode off' => [ + $object, 'color', 'object', 'pipeDelimited', false, 'color=R%7C100%7CG%7C200%7CB%7C150', + ], + // R=100&G=200&B=150 + 'pipeDelimited object, explode on' => [ + $object, 'color', 'object', 'pipeDelimited', true, 'R=100&G=200&B=150', + ], + + // DEEP OBJECT + // color=blue + 'deepObject primitive, explode off' => [ + 'blue', 'color', 'string', 'deepObject', false, 'color=blue', + ], + 'deepObject primitive, explode on' => [ + 'blue', 'color', 'string', 'deepObject', true, 'color=blue', + ], + // color=blue,black,brown + 'deepObject array, explode off' => [ + $array, 'color', 'array', 'deepObject', false, 'color=blue%2Cblack%2Cbrown', + ], + // color=blue&color=black&color=brown + 'deepObject array, explode on' => [ + $array, 'color', 'array', 'deepObject', true, 'color=blue&color=black&color=brown', + ], + // color[R]=100&color[G]=200&color[B]=150 + 'deepObject object, explode off' => [ + $object, 'color', 'object', 'deepObject', false, 'color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150', + ], + // color[R]=100&color[G]=200&color[B]=150 + 'deepObject object, explode on' => [ + $object, 'color', 'object', 'deepObject', true, 'color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150', + ], + // filter[or][0][name]=John&filter[or][1][email]=john@doe.com + 'example from @nadar' => [ + [ + 'or' => + [ + ['name' => 'John'], + ['email' => 'john@doe.com'], + ], + ], + 'filter', + 'object', + 'deepObject', + true, + 'filter%5Bor%5D%5B0%5D%5Bname%5D=John&filter%5Bor%5D%5B1%5D%5Bemail%5D=john%40doe.com' + ], + ]; + } + + /** + * @covers ObjectSerializer::toQueryValue + * @dataProvider provideDeepObjects + */ + public function testDeepObjectStyleQueryParam( + $data, + $paramName, + $expected + ): void { + $value = ObjectSerializer::buildQuery(ObjectSerializer::toQueryValue($data, $paramName, 'object', 'deepObject', true)); + parse_str($value, $result); + $this->assertEquals($expected, $result); + } + + public function provideDeepObjects(): array + { + return [ + /** example @see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-examples */ + 'example OpenAPISpec doc' => [ + ['R' => 100, 'G' => 200, 'B' => 150], + 'color', + [ + 'color' => [ + 'R' => 100, + 'G' => 200, + 'B' => 150, + ], + ], + ], + /** example @see https://swagger.io/docs/specification/serialization/ */ + 'example Swagger doc' => [ + ['role' => 'admin', 'firstName' => 'Alex'], + 'id', + [ + 'id' => [ + 'role' => 'admin', + 'firstName' => 'Alex', + ], + ], + ], + ]; + } } diff --git a/samples/client/petstore/php/OpenAPIClient-php/tests/ParametersTest.php b/samples/client/petstore/php/OpenAPIClient-php/tests/ParametersTest.php index aed0fade808..f5a00efc6b8 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/tests/ParametersTest.php +++ b/samples/client/petstore/php/OpenAPIClient-php/tests/ParametersTest.php @@ -56,6 +56,27 @@ class ParametersTest extends TestCase $this->assertSame('{"foo":"bar"}', $request->getBody()->getContents()); } + /** + * @see https://github.com/OpenAPITools/openapi-generator/pull/11225 + * @dataProvider provideQueryParameters + */ + public function testQueryParameterCollectionFormatRequest($pipe, $ioutil, $http, $url, $context, $allow_empty, $language, $expected) + { + $request = $this->fakeApi->testQueryParameterCollectionFormatRequest($pipe, $ioutil, $http, $url, $context, $allow_empty, $language); + $this->assertEquals($expected, urldecode($request->getUri()->getQuery())); + } + + public function provideQueryParameters() + { + $array = ['blue', 'black', 'brown']; + $object = ['R' => 100, 'G' => 200, 'B' => 150]; + return [ + [ + $array, $array, $array, $array, $array, 'blue', $object, 'pipe=blue|black|brown&ioutil=blue,black,brown&http=blue black brown&url=blue,black,brown&context=blue&context=black&context=brown&R=100&G=200&B=150&allowEmpty=blue', + ], + ]; + } + // missing example for collection path param in config // public function testPathParamCollection() // {