Skip to content

Commit 2437d7f

Browse files
[PHP-Client] Allow Content-Type merge-match+json for encoding (OpenAPITools#19479)
* Allow Content-Type merge-match+json for encoding * Changes JSON recognition to more flexible regex * Removes now useless JSON format list * Removes empty spaces * Adds explanatory PHPDoc comment * Moves Json-detection to class HeaderSelector
1 parent d521cdd commit 2437d7f

File tree

12 files changed

+159
-74
lines changed

12 files changed

+159
-74
lines changed

.ddev/web-build/Dockerfile.maven

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
RUN apt update && apt install -y maven

modules/openapi-generator/src/main/resources/php/HeaderSelector.mustache

+29-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class HeaderSelector
7676
}
7777

7878
# If none of the available Accept headers is of type "json", then just use all them
79-
$headersWithJson = preg_grep('~(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$~', $accept);
79+
$headersWithJson = $this->selectJsonMimeList($accept);
8080
if (count($headersWithJson) === 0) {
8181
return implode(',', $accept);
8282
}
@@ -86,6 +86,34 @@ class HeaderSelector
8686
return $this->getAcceptHeaderWithAdjustedWeight($accept, $headersWithJson);
8787
}
8888

89+
/**
90+
* Detects whether a string contains a valid JSON mime type
91+
*
92+
* @param string $searchString
93+
* @return bool
94+
*/
95+
public function isJsonMime(string $searchString): bool
96+
{
97+
return preg_match('~^application/(json|[\w!#$&.+-^_]+\+json)\s*(;|$)~', $searchString) === 1;
98+
}
99+
100+
/**
101+
* Select all items from a list containing a JSON mime type
102+
*
103+
* @param array $mimeList
104+
* @return array
105+
*/
106+
private function selectJsonMimeList(array $mimeList): array {
107+
$jsonMimeList = [];
108+
foreach ($mimeList as $mime) {
109+
if($this->isJsonMime($mime)) {
110+
$jsonMimeList[] = $mime;
111+
}
112+
}
113+
return $jsonMimeList;
114+
}
115+
116+
89117
/**
90118
* Create an Accept header string from the given "Accept" headers array, recalculating all weights
91119
*

modules/openapi-generator/src/main/resources/php/libraries/psr-18/api.mustache

+2-2
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ use function sprintf;
613613
// for model (json/xml)
614614
{{#bodyParams}}
615615
if (isset(${{paramName}})) {
616-
if ($headers['Content-Type'] === 'application/json') {
616+
if ($this->headerSelector->isJsonMime($headers['Content-Type'])) {
617617
$httpBody = json_encode(ObjectSerializer::sanitizeForSerialization(${{paramName}}));
618618
} else {
619619
$httpBody = ${{paramName}};
@@ -637,7 +637,7 @@ use function sprintf;
637637
// for HTTP post (form)
638638
$httpBody = new MultipartStream($multipartContents);
639639

640-
} elseif ($headers['Content-Type'] === 'application/json') {
640+
} elseif ($this->headerSelector->isJsonMime($headers['Content-Type'])) {
641641
$httpBody = json_encode($formParams);
642642
643643
} else {

samples/client/petstore/php/OpenAPIClient-php/lib/HeaderSelector.php

+29-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private function selectAcceptHeader(array $accept): ?string
8585
}
8686

8787
# If none of the available Accept headers is of type "json", then just use all them
88-
$headersWithJson = preg_grep('~(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$~', $accept);
88+
$headersWithJson = $this->selectJsonMimeList($accept);
8989
if (count($headersWithJson) === 0) {
9090
return implode(',', $accept);
9191
}
@@ -95,6 +95,34 @@ private function selectAcceptHeader(array $accept): ?string
9595
return $this->getAcceptHeaderWithAdjustedWeight($accept, $headersWithJson);
9696
}
9797

98+
/**
99+
* Detects whether a string contains a valid JSON mime type
100+
*
101+
* @param string $searchString
102+
* @return bool
103+
*/
104+
public function isJsonMime(string $searchString): bool
105+
{
106+
return preg_match('~^application/(json|[\w!#$&.+-^_]+\+json)\s*(;|$)~', $searchString) === 1;
107+
}
108+
109+
/**
110+
* Select all items from a list containing a JSON mime type
111+
*
112+
* @param array $mimeList
113+
* @return array
114+
*/
115+
private function selectJsonMimeList(array $mimeList): array {
116+
$jsonMimeList = [];
117+
foreach ($mimeList as $mime) {
118+
if($this->isJsonMime($mime)) {
119+
$jsonMimeList[] = $mime;
120+
}
121+
}
122+
return $jsonMimeList;
123+
}
124+
125+
98126
/**
99127
* Create an Accept header string from the given "Accept" headers array, recalculating all weights
100128
*

samples/client/petstore/php/psr-18/lib/Api/AnotherFakeApi.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ public function call123TestSpecialTagsRequest($client)
376376

377377
// for model (json/xml)
378378
if (isset($client)) {
379-
if ($headers['Content-Type'] === 'application/json') {
379+
if ($this->headerSelector->isJsonMime($headers['Content-Type'])) {
380380
$httpBody = json_encode(ObjectSerializer::sanitizeForSerialization($client));
381381
} else {
382382
$httpBody = $client;
@@ -396,7 +396,7 @@ public function call123TestSpecialTagsRequest($client)
396396
// for HTTP post (form)
397397
$httpBody = new MultipartStream($multipartContents);
398398

399-
} elseif ($headers['Content-Type'] === 'application/json') {
399+
} elseif ($this->headerSelector->isJsonMime($headers['Content-Type'])) {
400400
$httpBody = json_encode($formParams);
401401

402402
} else {

samples/client/petstore/php/psr-18/lib/Api/DefaultApi.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ public function fooGetRequest()
371371
// for HTTP post (form)
372372
$httpBody = new MultipartStream($multipartContents);
373373

374-
} elseif ($headers['Content-Type'] === 'application/json') {
374+
} elseif ($this->headerSelector->isJsonMime($headers['Content-Type'])) {
375375
$httpBody = json_encode($formParams);
376376

377377
} else {

0 commit comments

Comments
 (0)