Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[php] use http_build_query for deepObject support #11225

Merged
merged 14 commits into from
Mar 22, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -148,22 +148,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;
}

/**
Expand Down Expand Up @@ -400,4 +439,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);
}
}
36 changes: 9 additions & 27 deletions modules/openapi-generator/src/main/resources/php/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down Expand Up @@ -615,7 +597,7 @@ use {{invokerPackage}}\ObjectSerializer;

} else {
// for HTTP post (form)
$httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
$httpBody = ObjectSerializer::buildQuery($queryParams);
ybelenko marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -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}" : ''),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ public function call123TestSpecialTagsRequest($client)

} else {
// for HTTP post (form)
$httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
$httpBody = ObjectSerializer::buildQuery($queryParams);
}
}

Expand All @@ -375,7 +375,7 @@ public function call123TestSpecialTagsRequest($client)
$headers
);

$query = \GuzzleHttp\Psr7\Query::build($queryParams);
$query = ObjectSerializer::buildQuery($queryParams);
return new Request(
'PATCH',
$this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ public function fooGetRequest()

} else {
// for HTTP post (form)
$httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
$httpBody = ObjectSerializer::buildQuery($queryParams);
}
}

Expand All @@ -350,7 +350,7 @@ public function fooGetRequest()
$headers
);

$query = \GuzzleHttp\Psr7\Query::build($queryParams);
$query = ObjectSerializer::buildQuery($queryParams);
return new Request(
'GET',
$this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
Expand Down
Loading