Skip to content
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
Expand Up @@ -41,43 +41,43 @@ class {{controllerName}} extends Controller
{{#allParams}}
{{^isPathParam}}
{{#isFile}}
${{paramName}} = $request->file('{{paramName}}');
${{paramName}} = $request->file('{{baseName}}');
{{/isFile}}
{{#isBoolean}}
${{paramName}} = $request->boolean('{{paramName}}');
${{paramName}} = $request->boolean('{{baseName}}');
{{/isBoolean}}
{{#isInteger}}
${{paramName}} = $request->integer('{{paramName}}');
${{paramName}} = $request->integer('{{baseName}}');
{{/isInteger}}
{{#isLong}}
${{paramName}} = $request->integer('{{paramName}}');
${{paramName}} = $request->integer('{{baseName}}');
{{/isLong}}
{{#isNumber}}
${{paramName}} = $request->float('{{paramName}}');
${{paramName}} = $request->float('{{baseName}}');
{{/isNumber}}
{{#isFloat}}
${{paramName}} = $request->float('{{paramName}}');
${{paramName}} = $request->float('{{baseName}}');
{{/isFloat}}
{{#isDouble}}
${{paramName}} = $request->float('{{paramName}}');
${{paramName}} = $request->float('{{baseName}}');
{{/isDouble}}
{{#isString}}
${{paramName}} = $request->string('{{paramName}}')->value();
${{paramName}} = $request->string('{{baseName}}')->value();
{{/isString}}
{{#isByteArray}}
${{paramName}} = $request->string('{{paramName}}')->value();
${{paramName}} = $request->string('{{baseName}}')->value();
{{/isByteArray}}
{{#isDateTime}}
${{paramName}} = $request->date('{{paramName}}');
${{paramName}} = $request->date('{{baseName}}');
{{/isDateTime}}
{{#isDate}}
${{paramName}} = $request->date('{{paramName}}');
${{paramName}} = $request->date('{{baseName}}');
{{/isDate}}
{{#isArray}}
${{paramName}} = $request->get('{{paramName}}');
${{paramName}} = $request->get('{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}{{paramName}}{{/isBodyParam}}');
{{/isArray}}
{{#isMap}}
${{paramName}} = $request->get('{{paramName}}');
${{paramName}} = $request->get('{{^isBodyParam}}{{baseName}}{{/isBodyParam}}{{#isBodyParam}}{{paramName}}{{/isBodyParam}}');
{{/isMap}}
{{^isPrimitiveType}}
{{^isContainer}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
$validator = Validator::make(
array_merge(
$request->all(),
[
{{#pathParams}}'{{paramName}}' => ${{paramName}},{{/pathParams}}
{{#pathParams}}'{{baseName}}' => ${{paramName}},{{/pathParams}}
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
],
$request->all(),
),
[
{{#allParams}}
{{^bodyParam}}
'{{paramName}}' => [
'{{baseName}}' => [
{{#isFile}}
'file',
{{/isFile}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.openapitools.codegen.php.laravel;

import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.testng.annotations.Test;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PhpLaravelServerCodegenTest {

/**
* Parameters whose spec (wire) name is not already a valid camelCase PHP identifier must be read
* from the request and validated under the wire name ({@code baseName}), not under the sanitized
* PHP variable name ({@code paramName}). Otherwise the generated controller reads the wrong key
* and the value is always null.
*/
@Test
public void shouldUseWireNameForRequestLookupsAndValidationKeys() throws Exception {
Map<String, Object> properties = new HashMap<>();

File output = Files.createTempDirectory("test").toFile();

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("php-laravel")
.setAdditionalProperties(properties)
.setInputSpec("src/test/resources/3_0/php-laravel/petstore-with-fake-endpoints-models-for-testing.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));

final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();

TestUtils.ensureContainsFile(files, output, "Http/Controllers/FakeController.php");
TestUtils.ensureContainsFile(files, output, "Http/Controllers/StoreController.php");
TestUtils.ensureContainsFile(files, output, "Http/Controllers/UserController.php");

Path fakeController = files.stream().filter(f -> f.getName().equals("FakeController.php")).findFirst().orElseThrow().toPath();

// request accessors use the wire name (snake_case) while the local variable keeps the sanitized name
TestUtils.assertFileContains(fakeController, "$filterClientName = $request->string('filter_client_name')->value();");
TestUtils.assertFileContains(fakeController, "$filterUserIds = $request->get('filter_user_ids');");
TestUtils.assertFileContains(fakeController, "$clientId = $request->integer('client_id');");

// validation rule keys must match $request->all(), i.e. the wire name
TestUtils.assertFileContains(fakeController, "'filter_client_name' => [");
TestUtils.assertFileContains(fakeController, "'filter_user_ids' => [");
TestUtils.assertFileContains(fakeController, "'client_id' => [");

// the buggy behaviour (reading under the sanitized identifier) must not reappear
TestUtils.assertFileNotContains(fakeController, "$request->string('filterClientName')");
TestUtils.assertFileNotContains(fakeController, "$request->get('filterUserIds')");
TestUtils.assertFileNotContains(fakeController, "$request->integer('clientId')");

// path parameters: the merged validation key and the rule key both use the wire name
Path storeController = files.stream().filter(f -> f.getName().equals("StoreController.php")).findFirst().orElseThrow().toPath();
TestUtils.assertFileContains(storeController, "'order_id' => $orderId,");
TestUtils.assertFileContains(storeController, "'order_id' => [");

// body parameters are out of scope and must stay byte-identical: no wire-name substitution for the request body
Path userController = files.stream().filter(f -> f.getName().equals("UserController.php")).findFirst().orElseThrow().toPath();
TestUtils.assertFileContains(userController, "$user = $request->get('user');");

output.deleteOnExit();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,49 @@ paths:
required:
- param
- param2
/fake/parameter-name-mapping:
get:
tags:
- fake
summary: test query parameter name sanitization
description: 'Query params whose spec names require PHP identifier sanitization (snake_case) must be read/validated under the wire name.'
operationId: getParameterNameMapping
parameters:
- name: filter_client_name
in: query
required: false
schema:
type: string
- name: filter_user_ids
in: query
required: false
schema:
type: array
items:
type: integer
responses:
'200':
description: successful operation
post:
tags:
- fake
summary: test form parameter name sanitization
description: 'Form param whose spec name requires PHP identifier sanitization (snake_case) must be read/validated under the wire name.'
operationId: postParameterNameMapping
responses:
'200':
description: successful operation
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
client_id:
description: form field whose name requires sanitization
type: integer
required:
- client_id
/fake/additionalProperties-reference:
post:
tags:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public function getDummy(Request $request): JsonResponse
{
$validator = Validator::make(
array_merge(
$request->all(),
[

],
$request->all(),
),
[
'paramCamelCase' => [
Expand Down
30 changes: 30 additions & 0 deletions samples/server/petstore/php-laravel/Api/FakeApiInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,36 @@ public function fakePropertyEnumIntegerSerialize(
;


/**
* Operation getParameterNameMapping
*
* test query parameter name sanitization
* @param null | string $filterClientName
* @param null | int[] $filterUserIds
* @return \OpenAPI\Server\Model\NoContent200
*/
public function getParameterNameMapping(
?string $filterClientName,
?array $filterUserIds,
):
\OpenAPI\Server\Model\NoContent200
;


/**
* Operation postParameterNameMapping
*
* test form parameter name sanitization
* @param int $clientId
* @return \OpenAPI\Server\Model\NoContent200
*/
public function postParameterNameMapping(
int $clientId,
):
\OpenAPI\Server\Model\NoContent200
;


/**
* Operation testAdditionalPropertiesReference
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public function call123TestSpecialTags(Request $request): JsonResponse
{
$validator = Validator::make(
array_merge(
$request->all(),
[

],
$request->all(),
),
[
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public function fooGet(Request $request): JsonResponse
{
$validator = Validator::make(
array_merge(
$request->all(),
[

],
$request->all(),
),
[
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public function testClassname(Request $request): JsonResponse
{
$validator = Validator::make(
array_merge(
$request->all(),
[

],
$request->all(),
),
[
],
Expand Down
Loading
Loading