Skip to content

Commit 9714d8f

Browse files
gijs-blankengijs.blanken@futureof.finance
authored andcommitted
preemptive work to support union types as soon as php serde supports them
1 parent 08f82ea commit 9714d8f

File tree

7 files changed

+179
-111
lines changed

7 files changed

+179
-111
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ public String getTypeDeclaration(Schema p) {
373373
} else if (StringUtils.isNotBlank(p.get$ref())) { // model
374374
String type = super.getTypeDeclaration(p);
375375
return (!languageSpecificPrimitives.contains(type))
376-
? "\\" + modelPackage + "\\" + type : type;
376+
? "\\" + modelPackage + "\\" + toModelName(type) : type;
377377
}
378378
return super.getTypeDeclaration(p);
379379
}
@@ -401,6 +401,10 @@ public String getSchemaType(Schema p) {
401401
openAPIType = "UNKNOWN_OPENAPI_TYPE";
402402
}
403403

404+
if ((p.getAnyOf() != null && !p.getAnyOf().isEmpty()) || (p.getOneOf() != null && !p.getOneOf().isEmpty())) {
405+
return openAPIType;
406+
}
407+
404408
if (typeMapping.containsKey(openAPIType)) {
405409
type = typeMapping.get(openAPIType);
406410
if (languageSpecificPrimitives.contains(type)) {
@@ -909,4 +913,28 @@ public boolean isDataTypeString(String dataType) {
909913
public GeneratorLanguage generatorLanguage() {
910914
return GeneratorLanguage.PHP;
911915
}
916+
917+
@Override
918+
public String toOneOfName(List<String> names, Schema composedSchema) {
919+
List<Schema> schemas = ModelUtils.getInterfaces(composedSchema);
920+
921+
List<String> types = new ArrayList<>();
922+
for (Schema s : schemas) {
923+
types.add(getTypeDeclaration(s));
924+
}
925+
926+
return String.join("|", types);
927+
}
928+
929+
@Override
930+
public String toAllOfName(List<String> names, Schema composedSchema) {
931+
List<Schema> schemas = ModelUtils.getInterfaces(composedSchema);
932+
933+
List<String> types = new ArrayList<>();
934+
for (Schema s : schemas) {
935+
types.add(getTypeDeclaration(s));
936+
}
937+
938+
return String.join("&", types);
939+
}
912940
}

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpLaravelServerCodegen.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
import io.swagger.v3.oas.models.media.Schema;
88
import io.swagger.v3.oas.models.parameters.Parameter;
99
import io.swagger.v3.oas.models.responses.ApiResponse;
10-
import org.openapitools.codegen.*;
10+
import org.openapitools.codegen.CliOption;
11+
import org.openapitools.codegen.CodegenConfig;
12+
import org.openapitools.codegen.CodegenType;
13+
import org.openapitools.codegen.SupportingFile;
1114
import org.openapitools.codegen.model.ModelMap;
12-
import org.openapitools.codegen.model.ModelsMap;
1315
import org.openapitools.codegen.model.OperationMap;
1416
import org.openapitools.codegen.model.OperationsMap;
17+
import org.openapitools.codegen.utils.ModelUtils;
1518
import org.slf4j.Logger;
1619
import org.slf4j.LoggerFactory;
1720

@@ -23,6 +26,7 @@
2326
import static org.openapitools.codegen.utils.StringUtils.camelize;
2427

2528
public class PhpLaravelServerCodegen extends AbstractPhpCodegen implements CodegenConfig {
29+
private static final String AUTOWIRE = "autowire";
2630
private final Logger LOGGER = LoggerFactory.getLogger(PhpLaravelServerCodegen.class);
2731

2832
public CodegenType getTag() {
@@ -39,6 +43,8 @@ public String getHelp() {
3943

4044
protected String controllerDirName = "Http\\Controllers";
4145
protected String controllerPackage;
46+
protected String routesFileName = "routes.php";
47+
protected String routesDirectory = "";
4248

4349
public PhpLaravelServerCodegen() {
4450
super();
@@ -47,6 +53,10 @@ public PhpLaravelServerCodegen() {
4753
embeddedTemplateDir = templateDir = "php-laravel";
4854
variableNamingConvention = "camelCase";
4955

56+
// We need inline enums to be resolved to a separate model so that
57+
// anyOf/oneOf that contain them work correctly.
58+
inlineSchemaOption.put("RESOLVE_INLINE_ENUMS", "true");
59+
5060
modelDocTemplateFiles.clear();
5161
apiDocTemplateFiles.clear();
5262
apiTestTemplateFiles.clear();
@@ -61,10 +71,20 @@ public PhpLaravelServerCodegen() {
6171

6272
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
6373
supportingFiles.add(new SupportingFile("composer.mustache", "", "composer.json"));
64-
supportingFiles.add(new SupportingFile("routes.mustache", "", "routes.php"));
6574

6675
typeMapping.put("file", "\\Illuminate\\Http\\UploadedFile");
6776
languageSpecificPrimitives.add("\\Illuminate\\Http\\UploadedFile");
77+
78+
cliOptions.add(new CliOption(AUTOWIRE, "Should autowire by enabled.").defaultValue("false"));
79+
}
80+
81+
@Override
82+
public void processOpts() {
83+
super.processOpts();
84+
85+
vendorExtensions.put("x-autowire", additionalProperties.getOrDefault(AUTOWIRE, "false").equals("true"));
86+
87+
supportingFiles.add(new SupportingFile("routes.mustache", routesDirectory, routesFileName));
6888
}
6989

7090
@Override
@@ -161,4 +181,18 @@ public String toApiName(String name) {
161181
protected String toControllerName(String name) {
162182
return camelize(name) + "Controller";
163183
}
184+
185+
@Override
186+
protected String getParameterDataType(Parameter parameter, Schema schema) {
187+
if (parameter.get$ref() != null) {
188+
String refName = ModelUtils.getSimpleRef(parameter.get$ref());
189+
return toModelName(refName);
190+
}
191+
return null;
192+
}
193+
194+
@Override
195+
public String getSchemaType(Schema p) {
196+
return super.getSchemaType(p);
197+
}
164198
}

modules/openapi-generator/src/main/resources/php-laravel/api.mustache

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
namespace {{apiPackage}};
44

5+
{{#vendorExtensions.x-autowire}}
6+
use Attributes\Autowire;
7+
{{/vendorExtensions.x-autowire}}
8+
59
{{#operations}}
10+
{{#vendorExtensions.x-autowire}}
11+
#[Autowire]
12+
{{/vendorExtensions.x-autowire}}
613
interface {{classname}} {
714
815
{{#operation}}

modules/openapi-generator/src/main/resources/php-laravel/api_controller.mustache

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ class {{controllerName}} extends Controller
3434
* @deprecated
3535
{{/isDeprecated}}
3636
*/
37-
public function {{operationId}}(Request $request): JsonResponse
37+
public function {{operationId}}(Request $request{{#pathParams}}, {{dataType}} ${{paramName}}{{/pathParams}}): JsonResponse
3838
{
3939
{{>api_validation}}
4040

4141
{{#allParams}}
42+
{{^bodyParam}}
43+
{{^isPathParam}}
4244
{{#isFile}}
4345
${{paramName}} = $request->file('{{paramName}}');
4446
{{/isFile}}
@@ -78,13 +80,11 @@ class {{controllerName}} extends Controller
7880
{{#isMap}}
7981
${{paramName}} = $request->get('{{paramName}}');
8082
{{/isMap}}
81-
{{#isModel}}
82-
${{paramName}} = $this->serde->deserialize($request->get('{{paramName}}'), from: 'array', to: {{dataType}}::class);
83-
84-
if (${{paramName}} === null) {
85-
return response()->json(['error' => 'Invalid input'], 400);
86-
}
87-
{{/isModel}}
83+
{{/isPathParam}}
84+
{{/bodyParam}}
85+
{{#bodyParam}}
86+
${{paramName}} = $this->serde->deserialize($request->getContent(), from: 'json', to: {{dataType}}::class);
87+
{{/bodyParam}}
8888

8989
{{/allParams}}
9090
try {
@@ -97,50 +97,22 @@ class {{controllerName}} extends Controller
9797
{{#responses}}
9898
{{#isArray}}
9999
if (is_array($apiResult)) {
100-
$responseBody = $this->serde->serialize($apiResult, format: 'array');
101-
102-
if ($responseBody === null) {
103-
return response()->json(['error' => 'Failed to parse api output'], 500);
104-
}
105-
106-
if ($responseBody === []) {
107-
abort({{code}});
108-
}
109-
110-
return response()->json($responseBody, {{code}});
100+
$serialized = array_map(fn ($item) => $this->serde->serialize($item, format: 'array'), $apiResult);
101+
return response()->json($serialized, {{code}});
111102
}
112103
113104
{{/isArray}}
114105
{{#isMap}}
115106
if (is_array($apiResult)) {
116-
$responseBody = $this->serde->serialize($apiResult, format: 'array');
117-
118-
if ($responseBody === null) {
119-
return response()->json(['error' => 'Failed to parse api output'], 500);
120-
}
121-
122-
if ($responseBody === []) {
123-
abort({{code}});
124-
}
125-
126-
return response()->json($responseBody, {{code}});
107+
$serialized = array_map(fn ($item) => $this->serde->serialize($item, format: 'array'), $apiResult);
108+
return response()->json($serialized, {{code}});
127109
}
128110
129111
{{/isMap}}
130112
{{^isArray}}
131113
{{^isMap}}
132114
if ($apiResult instanceof {{dataType}}) {
133-
$responseBody = $this->serde->serialize($apiResult, format: 'array');
134-
135-
if ($responseBody === null) {
136-
return response()->json(['error' => 'Failed to parse api output'], 500);
137-
}
138-
139-
if ($responseBody === []) {
140-
abort({{code}});
141-
}
142-
143-
return response()->json($responseBody, {{code}});
115+
return response()->json($this->serde->serialize($apiResult, format: 'array'), {{code}});
144116
}
145117
146118
{{/isMap}}

modules/openapi-generator/src/main/resources/php-laravel/api_validation.mustache

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,77 @@
1-
$validator = Validator::make($request->all(), [
2-
{{#allParams}}
3-
'{{paramName}}' => [
4-
{{#isFile}}
5-
'file',
6-
{{/isFile}}
7-
{{#required}}
8-
'required',
9-
{{/required}}
10-
{{#minLength}}
11-
'min:{{minLength}}',
12-
{{/minLength}}
13-
{{#maxLength}}
14-
'max:{{maxLength}}',
15-
{{/maxLength}}
16-
{{#pattern}}
17-
'regex:{{{pattern}}}',
18-
{{/pattern}}
19-
{{#minimum}}
20-
{{#exclusiveMinimum}}
21-
'gt:{{minimum}}',
22-
{{/exclusiveMinimum}}
23-
{{^exclusiveMinimum}}
24-
'gte:{{minimum}}',
25-
{{/exclusiveMinimum}}
26-
{{/minimum}}
27-
{{#maximum}}
28-
{{#exclusiveMaximum}}
29-
'lt:{{maximum}}',
30-
{{/exclusiveMaximum}}
31-
{{^exclusiveMaximum}}
32-
'lte:{{maximum}}',
33-
{{/exclusiveMaximum}}
34-
{{/maximum}}
35-
{{#minItems}}
36-
'min:{{minItems}}',
37-
{{/minItems}}
38-
{{#maxItems}}
39-
'max:{{maxItems}}',
40-
{{/maxItems}}
41-
{{#isString}}
42-
'string',
43-
{{/isString}}
44-
{{#isInteger}}
45-
'integer',
46-
{{/isInteger}}
47-
{{#isLong}}
48-
'integer',
49-
{{/isLong}}
50-
{{#isNumeric}}
51-
'numeric',
52-
{{/isNumeric}}
53-
{{#isBoolean}}
54-
'boolean',
55-
{{/isBoolean}}
56-
{{#isArray}}
57-
'array',
58-
{{/isArray}}
59-
{{#isDateTime}}
60-
'date',
61-
{{/isDateTime}}
1+
$validator = Validator::make(
2+
array_merge(
3+
[
4+
{{#pathParams}}'{{paramName}}' => ${{paramName}},{{/pathParams}}
5+
],
6+
$request->all(),
7+
),
8+
[
9+
{{#allParams}}
10+
{{^bodyParam}}
11+
'{{paramName}}' => [
12+
{{#isFile}}
13+
'file',
14+
{{/isFile}}
15+
{{#required}}
16+
'required',
17+
{{/required}}
18+
{{#minLength}}
19+
'min:{{minLength}}',
20+
{{/minLength}}
21+
{{#maxLength}}
22+
'max:{{maxLength}}',
23+
{{/maxLength}}
24+
{{#pattern}}
25+
'regex:{{{pattern}}}',
26+
{{/pattern}}
27+
{{#minimum}}
28+
{{#exclusiveMinimum}}
29+
'gt:{{minimum}}',
30+
{{/exclusiveMinimum}}
31+
{{^exclusiveMinimum}}
32+
'gte:{{minimum}}',
33+
{{/exclusiveMinimum}}
34+
{{/minimum}}
35+
{{#maximum}}
36+
{{#exclusiveMaximum}}
37+
'lt:{{maximum}}',
38+
{{/exclusiveMaximum}}
39+
{{^exclusiveMaximum}}
40+
'lte:{{maximum}}',
41+
{{/exclusiveMaximum}}
42+
{{/maximum}}
43+
{{#minItems}}
44+
'min:{{minItems}}',
45+
{{/minItems}}
46+
{{#maxItems}}
47+
'max:{{maxItems}}',
48+
{{/maxItems}}
49+
{{#isString}}
50+
'string',
51+
{{/isString}}
52+
{{#isInteger}}
53+
'integer',
54+
{{/isInteger}}
55+
{{#isLong}}
56+
'integer',
57+
{{/isLong}}
58+
{{#isNumeric}}
59+
'numeric',
60+
{{/isNumeric}}
61+
{{#isBoolean}}
62+
'boolean',
63+
{{/isBoolean}}
64+
{{#isArray}}
65+
'array',
66+
{{/isArray}}
67+
{{#isDateTime}}
68+
'date',
69+
{{/isDateTime}}
70+
],
71+
{{/bodyParam}}
72+
{{/allParams}}
6273
],
63-
{{/allParams}}
64-
]);
74+
);
6575

6676
if ($validator->fails()) {
6777
\Illuminate\Support\Facades\Log::warning("Failed to validate input for testInlineFreeformAdditionalProperties", $validator->errors()->toArray());

0 commit comments

Comments
 (0)