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] Allow selecting Content-Type #13769

Merged
merged 5 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* ApiException
* HeaderSelector
* PHP version 7.4
*
* @category Class
Expand All @@ -18,10 +18,8 @@

namespace {{invokerPackage}};

use \Exception;

/**
* ApiException Class Doc Comment
* HeaderSelector Class Doc Comment
*
* @category Class
* @package {{invokerPackage}}
Expand All @@ -32,31 +30,25 @@ class HeaderSelector
{
/**
* @param string[] $accept
* @param string[] $contentTypes
* @return array
* @param string $contentType
* @param bool $isMultipart
* @return string[]
*/
public function selectHeaders($accept, $contentTypes)
public function selectHeaders(array $accept, string $contentType, bool $isMultipart): array
{
$headers = [];

$accept = $this->selectAcceptHeader($accept);
if ($accept !== null) {
$headers['Accept'] = $accept;
}
if(!$isMultipart) {
if($contentType === '') {
$contentType = 'application/json';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI. We can keep 'application/json' as the default for the time being if nothing is provided. For some other clients, we've removed such default as some servers do not expect "application/json" as the content-type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about what you want me to do here - the current code is doing exactly that: keeping application/json as default if nothing is provided... The "$isMultipart" check is just a rewrite of what the previous code used to do: if multipart is set, don't send any contentType header...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing to do. More of an FYI that something we need to change later.

}
$headers['Content-Type'] = $contentType;
}

$headers['Content-Type'] = $this->selectContentTypeHeader($contentTypes);
return $headers;
}

/**
* @param string[] $accept
* @return array
*/
public function selectHeadersForMultipart($accept)
{
$headers = $this->selectHeaders($accept, []);

unset($headers['Content-Type']);
return $headers;
}

Expand All @@ -77,22 +69,4 @@ class HeaderSelector
return implode(',', $accept);
}
}

/**
* Return the content type based on an array of content-type provided
*
* @param string[] $contentType Array fo content-type
*
* @return string Content-Type (e.g. application/json)
*/
private function selectContentTypeHeader($contentType)
{
if (count($contentType) === 0 || (count($contentType) === 1 && $contentType[0] === '')) {
return 'application/json';
} elseif (preg_grep("/application\/json/i", $contentType)) {
return 'application/json';
} else {
return implode(',', $contentType);
}
}
}
64 changes: 37 additions & 27 deletions modules/openapi-generator/src/main/resources/php/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,16 @@ use {{invokerPackage}}\ObjectSerializer;
*/
protected $hostIndex;

/**
/** @var string[] $contentTypes **/
public const contentTypes = [{{#operation}}
'{{{operationId}}}' => [{{#consumes}}
'{{{mediaType}}}',{{/consumes}}
{{^consumes}}
'application/json',
{{/consumes}} ],{{/operation}}
];

/**
* @param ClientInterface $client
* @param Configuration $config
* @param HeaderSelector $selector
Expand Down Expand Up @@ -151,6 +160,7 @@ use {{invokerPackage}}\ObjectSerializer;
* @param array $variables Associative array of variables to pass to the host. Defaults to empty array.
{{/-first}}
{{/servers}}
* @param string $contentType The value for the Content-Type header. Check self::contentTypes['{{{operationId}}}'] to see the possible values for this operation
*
* @throws \{{invokerPackage}}\ApiException on non-2xx response
* @throws \InvalidArgumentException
Expand All @@ -159,9 +169,9 @@ use {{invokerPackage}}\ObjectSerializer;
* @deprecated
{{/isDeprecated}}
*/
public function {{operationId}}({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}?int $hostIndex = null, array $variables = []{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
public function {{operationId}}({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}, {{/allParams}}{{#servers}}{{#-first}}?int $hostIndex = null, array $variables = [], {{/-first}}{{/servers}}string $contentType = self::contentTypes['{{{operationId}}}'][0]{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
{{#returnType}}list($response) = {{/returnType}}$this->{{operationId}}WithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}$hostIndex, $variables{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});{{#returnType}}
{{#returnType}}list($response) = {{/returnType}}$this->{{operationId}}WithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}, {{/allParams}}{{#servers}}{{#-first}}$hostIndex, $variables, {{/-first}}{{/servers}}$contentType{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});{{#returnType}}
return $response;{{/returnType}}
}

Expand Down Expand Up @@ -209,6 +219,7 @@ use {{invokerPackage}}\ObjectSerializer;
* @param array $variables Associative array of variables to pass to the host. Defaults to empty array.
{{/-first}}
{{/servers}}
* @param string $contentType The value for the Content-Type header. Check self::contentTypes['{{{operationId}}}'] to see the possible values for this operation
*
* @throws \{{invokerPackage}}\ApiException on non-2xx response
* @throws \InvalidArgumentException
Expand All @@ -217,9 +228,9 @@ use {{invokerPackage}}\ObjectSerializer;
* @deprecated
{{/isDeprecated}}
*/
public function {{operationId}}WithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}?int $hostIndex = null, array $variables = []{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
public function {{operationId}}WithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}, {{/allParams}}{{#servers}}{{#-first}}?int $hostIndex = null, array $variables = [], {{/-first}}{{/servers}}string $contentType = self::contentTypes['{{{operationId}}}'][0]{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
$request = $this->{{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}$hostIndex, $variables{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});
$request = $this->{{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}, {{/allParams}}{{#servers}}{{#-first}}$hostIndex, $variables, {{/-first}}{{/servers}}$contentType{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});

try {
$options = $this->createHttpClientOption();
Expand Down Expand Up @@ -367,16 +378,17 @@ use {{invokerPackage}}\ObjectSerializer;
* @param array $variables Associative array of variables to pass to the host. Defaults to empty array.
{{/-first}}
{{/servers}}
* @param string $contentType The value for the Content-Type header. Check self::contentTypes['{{{operationId}}}'] to see the possible values for this operation
*
* @throws \InvalidArgumentException
* @return \GuzzleHttp\Promise\PromiseInterface
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
public function {{operationId}}Async({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}?int $hostIndex = null, array $variables = []{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
public function {{operationId}}Async({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}, {{/allParams}}{{#servers}}{{#-first}}?int $hostIndex = null, array $variables = [], {{/-first}}{{/servers}}string $contentType = self::contentTypes['{{{operationId}}}'][0]{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
return $this->{{operationId}}AsyncWithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}$hostIndex, $variables{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
return $this->{{operationId}}AsyncWithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}, {{/allParams}}{{#servers}}{{#-first}}$hostIndex, $variables, {{/-first}}{{/servers}}$contentType{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
->then(
function ($response) {
return $response[0];
Expand Down Expand Up @@ -428,17 +440,18 @@ use {{invokerPackage}}\ObjectSerializer;
* @param array $variables Associative array of variables to pass to the host. Defaults to empty array.
{{/-first}}
{{/servers}}
* @param string $contentType The value for the Content-Type header. Check self::contentTypes['{{{operationId}}}'] to see the possible values for this operation
*
* @throws \InvalidArgumentException
* @return \GuzzleHttp\Promise\PromiseInterface
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
public function {{operationId}}AsyncWithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}?int $hostIndex = null, array $variables = []{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
public function {{operationId}}AsyncWithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}, {{/allParams}}{{#servers}}{{#-first}}?int $hostIndex = null, array $variables = [], {{/-first}}{{/servers}}string $contentType = self::contentTypes['{{{operationId}}}'][0]{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
$returnType = '{{{returnType}}}';
$request = $this->{{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}$hostIndex, $variables{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});
$request = $this->{{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}, {{/allParams}}{{#servers}}{{#-first}}$hostIndex, $variables, {{/-first}}{{/servers}}$contentType{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});

return $this->client
->sendAsync($request, $this->createHttpClientOption())
Expand Down Expand Up @@ -517,14 +530,15 @@ use {{invokerPackage}}\ObjectSerializer;
* @param array $variables Associative array of variables to pass to the host. Defaults to empty array.
{{/-first}}
{{/servers}}
* @param string $contentType The value for the Content-Type header. Check self::contentTypes['{{{operationId}}}'] to see the possible values for this operation
*
* @throws \InvalidArgumentException
* @return \GuzzleHttp\Psr7\Request
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
public function {{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#servers}}{{#-first}}{{#allParams}}{{#-first}}, {{/-first}}{{/allParams}}?int $hostIndex = null, array $variables = []{{/-first}}{{/servers}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
public function {{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}, {{/allParams}}{{#servers}}{{#-first}}?int $hostIndex = null, array $variables = [], {{/-first}}{{/servers}}string $contentType = self::contentTypes['{{{operationId}}}'][0]{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
{{#vendorExtensions.x-group-parameters}}
// unbox the parameters from the associative array
Expand All @@ -533,7 +547,9 @@ use {{invokerPackage}}\ObjectSerializer;
{{/allParams}}{{#servers.0}}
$hostIndex = $associative_array['hostIndex'];
$variables = array_key_exists('variables', $associative_array) ? $associative_array['variables'] : [];
{{/servers.0}}{{/vendorExtensions.x-group-parameters}}{{#allParams}}
{{/servers.0}}
$contentType = $associative_array['contentType'] ?? self::contentTypes['{{{operationId}}}'][0];
{{/vendorExtensions.x-group-parameters}}{{#allParams}}
{{#required}}
// verify the required parameter '{{paramName}}' is set
if (${{paramName}} === null || (is_array(${{paramName}}) && count(${{paramName}}) === 0)) {
Expand Down Expand Up @@ -578,9 +594,7 @@ use {{invokerPackage}}\ObjectSerializer;
throw new \InvalidArgumentException('invalid value for "${{paramName}}" when calling {{classname}}.{{operationId}}, number of items must be greater than or equal to {{minItems}}.');
}
{{/minItems}}

{{/hasValidation}}
{{/allParams}}
{{/hasValidation}}{{/allParams}}

$resourcePath = '{{{path}}}';
$formParams = [];
Expand Down Expand Up @@ -649,21 +663,17 @@ use {{invokerPackage}}\ObjectSerializer;
}
{{/formParams}}

if ($multipart) {
$headers = $this->headerSelector->selectHeadersForMultipart(
[{{#produces}}'{{{mediaType}}}'{{^-last}}, {{/-last}}{{/produces}}]
);
} else {
$headers = $this->headerSelector->selectHeaders(
[{{#produces}}'{{{mediaType}}}'{{^-last}}, {{/-last}}{{/produces}}],
[{{#consumes}}'{{{mediaType}}}'{{^-last}}, {{/-last}}{{/consumes}}]
);
}
$headers = $this->headerSelector->selectHeaders(
[{{#produces}}'{{{mediaType}}}', {{/produces}}],
$contentType,
$multipart
);

// for model (json/xml)
{{#bodyParams}}
if (isset(${{paramName}})) {
if ($headers['Content-Type'] === 'application/json') {
if (stripos($headers['Content-Type'], 'application/json') !== false) {
# if Content-Type contains "application/json", json_encode the body
$httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization(${{paramName}}));
} else {
$httpBody = ${{paramName}};
Expand All @@ -687,9 +697,9 @@ use {{invokerPackage}}\ObjectSerializer;
// for HTTP post (form)
$httpBody = new MultipartStream($multipartContents);

} elseif ($headers['Content-Type'] === 'application/json') {
} elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
# if Content-Type contains "application/json", json_encode the form parameters
$httpBody = \GuzzleHttp\json_encode($formParams);

} else {
// for HTTP post (form)
$httpBody = ObjectSerializer::buildQuery($formParams);
Expand Down
Loading