Skip to content

Commit b96012c

Browse files
committed
Fixed issue #128 - Fixed content type construction parameter generation.
1 parent 3d37544 commit b96012c

4 files changed

Lines changed: 85 additions & 16 deletions

File tree

example/PetStoreClient/doc/petstore3.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,21 @@
116116
"summary": "Add a new pet to the store",
117117
"description": "Add a new pet to the store",
118118
"operationId": "addPet",
119+
"parameters": [
120+
{
121+
"in" : "header",
122+
"name": "Content-Type",
123+
"required": true,
124+
"schema": {
125+
"type": "string",
126+
"enum": [
127+
"application/json",
128+
"approved",
129+
"delivered"
130+
]
131+
}
132+
}
133+
],
119134
"requestBody": {
120135
"description": "Create a new pet in the store",
121136
"content": {

example/PetStoreClient/src/Request/AddPetRequest.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,24 @@
1111
namespace OpenApi\PetStoreClient\Request;
1212

1313
use OpenApi\PetStoreClient\Schema\Pet;
14+
use OpenApi\PetStoreClient\Schema\SerializableInterface;
1415

1516
class AddPetRequest implements RequestInterface
1617
{
17-
private Pet $pet;
18+
public const CONTENT_TYPE_APPLICATION_JSON = 'application/json';
19+
20+
public const CONTENT_TYPE_APPROVED = 'approved';
21+
22+
public const CONTENT_TYPE_DELIVERED = 'delivered';
1823

1924
private string $contentType;
2025

21-
public function __construct(Pet $pet, string $contentType)
26+
private Pet $pet;
27+
28+
public function __construct(string $contentType, Pet $pet)
2229
{
23-
$this->pet = $pet;
2430
$this->contentType = $contentType;
31+
$this->pet = $pet;
2532
}
2633

2734
public function getContentType(): string
@@ -56,7 +63,11 @@ public function getCookies(): array
5663

5764
public function getHeaders(): array
5865
{
59-
return ['Content-Type' => $this->contentType];
66+
return array_merge(['Content-Type' => $this->contentType], array_map(static function ($value) {
67+
return $value instanceof SerializableInterface ? $value->toArray() : $value;
68+
}, array_filter(['Content-Type' => $this->contentType], static function ($value) {
69+
return null !== $value;
70+
})));
6071
}
6172

6273
/**

example/petstore3.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,21 @@
116116
"summary": "Add a new pet to the store",
117117
"description": "Add a new pet to the store",
118118
"operationId": "addPet",
119+
"parameters": [
120+
{
121+
"in" : "header",
122+
"name": "Content-Type",
123+
"required": true,
124+
"schema": {
125+
"type": "string",
126+
"enum": [
127+
"application/json",
128+
"approved",
129+
"delivered"
130+
]
131+
}
132+
}
133+
],
119134
"requestBody": {
120135
"description": "Create a new pet in the store",
121136
"content": {

src/Generator/RequestGenerator.php

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ class RequestGenerator extends MutatorAccessorClassGeneratorAbstract
2828

2929
public const SUBDIRECTORY = 'Request/';
3030

31+
private const CONTENT_TYPE_PARAMETER_NAME = 'contentType';
32+
3133
/** @var SecurityStrategyInterface[] */
3234
private array $securityStrategies;
3335

36+
private bool $isContentTypeEnum = false;
37+
3438
public function __construct(
3539
string $baseNamespace,
3640
CodeBuilder $builder,
@@ -45,6 +49,7 @@ public function __construct(
4549
public function generate(Specification $specification, PhpFileCollection $fileRegistry): void
4650
{
4751
foreach ($specification->getOperations() as $operation) {
52+
$this->isContentTypeEnum = false;
4853
$this->generateRequest($fileRegistry, $operation, $specification);
4954
}
5055
}
@@ -92,6 +97,7 @@ protected function generateEnums(Request $request): array
9297
protected function generateProperties(Request $request, Operation $operation, Specification $specification): array
9398
{
9499
$statements = [];
100+
$fieldNames = [];
95101

96102
foreach ($request->fields as $field) {
97103
if ($field->isComposite()) {
@@ -117,13 +123,21 @@ protected function generateProperties(Request $request, Operation $operation, Sp
117123
}
118124

119125
$statements[] = $this->generateProperty($field);
126+
$fieldNames[] = $field->getPhpVariableName();
120127
}
121128

122-
$default = null;
123-
if (count($request->bodyContentTypes) < 2) {
129+
$default = null;
130+
$bodyContentTypesCount = count($request->bodyContentTypes);
131+
if ($bodyContentTypesCount < 2) {
124132
$default = $this->builder->val($request->bodyContentTypes[0] ?? '');
125133
}
126-
$statements[] = $this->builder->localProperty('contentType', 'string', 'string', false, $default);
134+
135+
if (
136+
($bodyContentTypesCount < 2 || !$this->phpVersion->isConstructorPropertyPromotionSupported())
137+
&& !in_array(self::CONTENT_TYPE_PARAMETER_NAME, $fieldNames, true)
138+
) {
139+
$statements[] = $this->builder->localProperty(self::CONTENT_TYPE_PARAMETER_NAME, 'string', 'string', false, $default);
140+
}
127141

128142
foreach ($this->securityStrategies as $securityStrategy) {
129143
array_push($statements, ...$securityStrategy->getProperties($operation, $specification));
@@ -137,6 +151,7 @@ protected function generateConstructor(
137151
Operation $operation,
138152
Specification $specification
139153
): ?ClassMethod {
154+
$paramNames = [];
140155
$params = [];
141156
$paramInits = [];
142157
$validations = [];
@@ -163,7 +178,16 @@ protected function generateConstructor(
163178
}
164179
}
165180

166-
$params[] = $param;
181+
$params[] = $param;
182+
$paramNames[] = $field->getPhpVariableName();
183+
184+
if (
185+
$field->isEnum()
186+
&& $this->phpVersion->isEnumSupported()
187+
&& $field->getPhpVariableName() === self::CONTENT_TYPE_PARAMETER_NAME
188+
) {
189+
$this->isContentTypeEnum = true;
190+
}
167191

168192
$paramInits[] = $this->builder->assign(
169193
$this->builder->localPropertyFetch($field->getPhpVariableName()),
@@ -177,14 +201,12 @@ protected function generateConstructor(
177201
array_push($paramInits, ...$securityStrategy->getConstructorParamInits($operation, $specification));
178202
}
179203

180-
if (count($request->bodyContentTypes) > 1) {
181-
$contentTypeVariableName = 'contentType';
182-
183-
$params[] = $this->builder->param($contentTypeVariableName)->setType('string');
204+
if (count($request->bodyContentTypes) > 1 && !in_array(self::CONTENT_TYPE_PARAMETER_NAME, $paramNames, true)) {
205+
$params[] = $this->builder->param(self::CONTENT_TYPE_PARAMETER_NAME)->setType('string');
184206

185207
$paramInits[] = $this->builder->assign(
186-
$this->builder->localPropertyFetch($contentTypeVariableName),
187-
$this->builder->var($contentTypeVariableName)
208+
$this->builder->localPropertyFetch(self::CONTENT_TYPE_PARAMETER_NAME),
209+
$this->builder->var(self::CONTENT_TYPE_PARAMETER_NAME)
188210
);
189211
}
190212

@@ -242,8 +264,14 @@ private function generateSetters(Request $request): array
242264

243265
private function generateGetContentType(): ClassMethod
244266
{
245-
$return = $this->builder->return($this->builder->localPropertyFetch('contentType'));
246-
$returnType = 'string';
267+
$localProperty = $this->builder->localPropertyFetch(self::CONTENT_TYPE_PARAMETER_NAME);
268+
$returnType = 'string';
269+
270+
if ($this->isContentTypeEnum) {
271+
$localProperty = $this->builder->propertyFetch($localProperty, 'value');
272+
}
273+
274+
$return = $this->builder->return($localProperty);
247275

248276
return $this
249277
->builder

0 commit comments

Comments
 (0)