diff --git a/.github/workflows/samples-php8.yaml b/.github/workflows/samples-php8.yaml index 93c4e80724ea..1e3fe1701e4a 100644 --- a/.github/workflows/samples-php8.yaml +++ b/.github/workflows/samples-php8.yaml @@ -6,11 +6,13 @@ on: - samples/server/petstore/php-symfony/SymfonyBundle-php/** - samples/server/petstore/php-flight/** - samples/server/petstore/php-laravel/** + - samples/server/petstore/php-laravel-issue-21334/** pull_request: paths: - samples/server/petstore/php-symfony/SymfonyBundle-php/** - samples/server/petstore/php-flight/** - samples/server/petstore/php-laravel/** + - samples/server/petstore/php-laravel-issue-21334/** jobs: build: name: Build PHP projects @@ -28,6 +30,7 @@ jobs: - samples/server/petstore/php-symfony/SymfonyBundle-php/ - samples/server/petstore/php-flight/ - samples/server/petstore/php-laravel/ + - samples/server/petstore/php-laravel-issue-21334/ steps: - uses: actions/checkout@v4 - name: Setup PHP with tools diff --git a/bin/configs/php-laravel-issue-21334.yaml b/bin/configs/php-laravel-issue-21334.yaml new file mode 100644 index 000000000000..8c24583b9dba --- /dev/null +++ b/bin/configs/php-laravel-issue-21334.yaml @@ -0,0 +1,8 @@ +generatorName: php-laravel +outputDir: samples/server/petstore/php-laravel-issue-21334 +inputSpec: modules/openapi-generator/src/test/resources/3_0/issue21334.yaml +templateDir: modules/openapi-generator/src/main/resources/php-laravel +gitUserId: openapitools +gitRepoId: petstore +additionalProperties: + variableNamingConvention: "original" diff --git a/docs/generators/php-dt.md b/docs/generators/php-dt.md index 2cfe33eb3a7a..67e83ce4c8a7 100644 --- a/docs/generators/php-dt.md +++ b/docs/generators/php-dt.md @@ -38,7 +38,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|snake_case| ## IMPORT MAPPING diff --git a/docs/generators/php-flight.md b/docs/generators/php-flight.md index 8b7c90a069be..fed502b1d1db 100644 --- a/docs/generators/php-flight.md +++ b/docs/generators/php-flight.md @@ -38,7 +38,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |camelCase| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|camelCase| ## IMPORT MAPPING diff --git a/docs/generators/php-laravel.md b/docs/generators/php-laravel.md index 9f575cdc4e12..52937aef3fef 100644 --- a/docs/generators/php-laravel.md +++ b/docs/generators/php-laravel.md @@ -38,7 +38,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|snake_case| ## IMPORT MAPPING diff --git a/docs/generators/php-lumen.md b/docs/generators/php-lumen.md index 39203422b3d4..5c54efc5701b 100644 --- a/docs/generators/php-lumen.md +++ b/docs/generators/php-lumen.md @@ -37,7 +37,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|snake_case| ## IMPORT MAPPING diff --git a/docs/generators/php-mezzio-ph.md b/docs/generators/php-mezzio-ph.md index d724c85d0878..2d2bc470d073 100644 --- a/docs/generators/php-mezzio-ph.md +++ b/docs/generators/php-mezzio-ph.md @@ -38,7 +38,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|snake_case| ## IMPORT MAPPING diff --git a/docs/generators/php-nextgen.md b/docs/generators/php-nextgen.md index 434804de2089..339f665da0a8 100644 --- a/docs/generators/php-nextgen.md +++ b/docs/generators/php-nextgen.md @@ -39,7 +39,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| |supportStreaming|Support streaming endpoint| |false| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|snake_case| ## IMPORT MAPPING diff --git a/docs/generators/php-slim4.md b/docs/generators/php-slim4.md index 7f3ca80191de..5062d3d75475 100644 --- a/docs/generators/php-slim4.md +++ b/docs/generators/php-slim4.md @@ -38,7 +38,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |camelCase| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|camelCase| ## IMPORT MAPPING diff --git a/docs/generators/php-symfony.md b/docs/generators/php-symfony.md index 0e183bc9cc2e..a516a3fac4e5 100644 --- a/docs/generators/php-symfony.md +++ b/docs/generators/php-symfony.md @@ -43,7 +43,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|snake_case| ## IMPORT MAPPING diff --git a/docs/generators/php.md b/docs/generators/php.md index b3997fb00d7e..d245377279ee 100644 --- a/docs/generators/php.md +++ b/docs/generators/php.md @@ -39,7 +39,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |srcBasePath|The directory to serve as source root.| |null| -|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case| +|variableNamingConvention|naming convention of variable name, e.g. camelCase.|
**camelCase**
Use camelCase convention
**PascalCase**
Use PascalCase convention
**snake_case**
Use snake_case convention
**original**
Do not change the variable name
|snake_case| ## IMPORT MAPPING diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java index 35a411d708ae..68520b123d99 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPhpCodegen.java @@ -149,6 +149,10 @@ public AbstractPhpCodegen() { cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC)); cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC)); cliOptions.add(new CliOption(VARIABLE_NAMING_CONVENTION, "naming convention of variable name, e.g. camelCase.") + .addEnum("camelCase", "Use camelCase convention") + .addEnum("PascalCase", "Use PascalCase convention") + .addEnum("snake_case", "Use snake_case convention") + .addEnum("original", "Do not change the variable name") .defaultValue("snake_case")); cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, "The main namespace to use for all classes. e.g. Yay\\Pets")); cliOptions.add(new CliOption(PACKAGE_NAME, "The main package name for classes. e.g. GeneratedPetstore")); @@ -451,6 +455,8 @@ public String toVarName(String name) { name = camelize(name, LOWERCASE_FIRST_LETTER); } else if ("PascalCase".equals(variableNamingConvention)) { name = camelize(name, UPPERCASE_FIRST_CHAR); + } else if ("original".equals(variableNamingConvention)) { + // return the name as it is } else { // default to snake case // return the name in underscore style // PhoneNumber => phone_number diff --git a/modules/openapi-generator/src/test/resources/3_0/issue21334.yaml b/modules/openapi-generator/src/test/resources/3_0/issue21334.yaml new file mode 100644 index 000000000000..7de5bd742787 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue21334.yaml @@ -0,0 +1,43 @@ +openapi: 3.0.3 +info: + title: Issue 21334 - Abstract PHP Variable Naming Convention + description: '' + version: 1.0.0 +paths: + /dummy: + get: + description: '' + operationId: getDummy + parameters: + - name: paramCamelCase + in: query + required: false + schema: + type: string + - name: ParamPascalCase + in: query + required: false + schema: + type: string + - name: param_withRandomCase + in: query + required: false + schema: + type: string + responses: + '200': + description: successful operation +components: + schemas: + SampleModelToTestNamingConvention: + type: object + properties: + propCamelCase: + type: string + default: 'defaultName' + PropPascalCase: + type: string + default: 'DefaultName' + Prop_withRandomCase: + type: string + default: 'defaultName' diff --git a/samples/server/petstore/php-laravel-issue-21334/.gitignore b/samples/server/petstore/php-laravel-issue-21334/.gitignore new file mode 100644 index 000000000000..42cd73d9573d --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/.gitignore @@ -0,0 +1 @@ +/vendor/ \ No newline at end of file diff --git a/samples/server/petstore/php-laravel-issue-21334/.openapi-generator-ignore b/samples/server/petstore/php-laravel-issue-21334/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/php-laravel-issue-21334/.openapi-generator/FILES b/samples/server/petstore/php-laravel-issue-21334/.openapi-generator/FILES new file mode 100644 index 000000000000..2184342984b5 --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/.openapi-generator/FILES @@ -0,0 +1,9 @@ +.gitignore +Api/DefaultApiInterface.php +Http/Controllers/DefaultController.php +Model/NoContent200.php +Model/SampleModelToTestNamingConvention.php +README.md +composer.json +phpunit.xml.dist +routes.php diff --git a/samples/server/petstore/php-laravel-issue-21334/.openapi-generator/VERSION b/samples/server/petstore/php-laravel-issue-21334/.openapi-generator/VERSION new file mode 100644 index 000000000000..4c631cf217a2 --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.14.0-SNAPSHOT diff --git a/samples/server/petstore/php-laravel-issue-21334/Api/DefaultApiInterface.php b/samples/server/petstore/php-laravel-issue-21334/Api/DefaultApiInterface.php new file mode 100644 index 000000000000..09bf504a9954 --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/Api/DefaultApiInterface.php @@ -0,0 +1,42 @@ + https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/php-laravel/ + */ + + +namespace OpenAPI\Server\Api; + + +interface DefaultApiInterface { + + + /** + * Operation getDummy + * @param null | string $paramCamelCase + * @param null | string $ParamPascalCase + * @param null | string $param_withRandomCase + * @return \OpenAPI\Server\Model\NoContent200 + */ + public function getDummy( + ?string $paramCamelCase, + ?string $ParamPascalCase, + ?string $param_withRandomCase, + ): + \OpenAPI\Server\Model\NoContent200 + ; + +} diff --git a/samples/server/petstore/php-laravel-issue-21334/Http/Controllers/DefaultController.php b/samples/server/petstore/php-laravel-issue-21334/Http/Controllers/DefaultController.php new file mode 100644 index 000000000000..a84092ad936c --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/Http/Controllers/DefaultController.php @@ -0,0 +1,98 @@ + https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/php-laravel/ + */ + + +namespace OpenAPI\Server\Http\Controllers; + +use Crell\Serde\SerdeCommon; +use Illuminate\Routing\Controller; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Validator; + + +use OpenAPI\Server\Api\DefaultApiInterface; + +class DefaultController extends Controller +{ + /** + * Constructor + */ + public function __construct( + private readonly DefaultApiInterface $api, + private readonly SerdeCommon $serde = new SerdeCommon(), + ) + { + } + + /** + * Operation getDummy + * + * . + * + */ + public function getDummy(Request $request): JsonResponse + { + $validator = Validator::make( + array_merge( + [ + + ], + $request->all(), + ), + [ + 'paramCamelCase' => [ + 'string', + ], + 'ParamPascalCase' => [ + 'string', + ], + 'param_withRandomCase' => [ + 'string', + ], + ], + ); + + if ($validator->fails()) { + return response()->json(['error' => 'Invalid input'], 400); + } + + $paramCamelCase = $request->string('paramCamelCase')->value(); + + $ParamPascalCase = $request->string('ParamPascalCase')->value(); + + $param_withRandomCase = $request->string('param_withRandomCase')->value(); + + try { + $apiResult = $this->api->getDummy($paramCamelCase, $ParamPascalCase, $param_withRandomCase); + } catch (\Exception $exception) { + // This shouldn't happen + report($exception); + return response()->json(['error' => $exception->getMessage()], 500); + } + + if ($apiResult instanceof \OpenAPI\Server\Model\NoContent200) { + return response()->json($this->serde->serialize($apiResult, format: 'array'), 200); + } + + + // This shouldn't happen + return response()->abort(500); + } +} diff --git a/samples/server/petstore/php-laravel-issue-21334/Model/NoContent200.php b/samples/server/petstore/php-laravel-issue-21334/Model/NoContent200.php new file mode 100644 index 000000000000..c850d29f5a59 --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/Model/NoContent200.php @@ -0,0 +1,46 @@ + https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/php-laravel/ + */ + + +/** + * NoContent200 + */ +namespace OpenAPI\Server\Model; + +/** + * NoContent200 + * @description No content for 200 + */ +use Crell\Serde\Renaming\Cases; +use Crell\Serde\Attributes as Serde; + +#[Serde\ClassSettings(renameWith: Cases::snake_case)] +class NoContent200 +{ + /** + * + * dummy property for no-content responses + * @param null | string $dummy + */ + + public function __construct( + public ?string $dummy = null, + ) {} +} + diff --git a/samples/server/petstore/php-laravel-issue-21334/Model/SampleModelToTestNamingConvention.php b/samples/server/petstore/php-laravel-issue-21334/Model/SampleModelToTestNamingConvention.php new file mode 100644 index 000000000000..1901c843ee4d --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/Model/SampleModelToTestNamingConvention.php @@ -0,0 +1,53 @@ + https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/php-laravel/ + */ + + +/** + * SampleModelToTestNamingConvention + */ +namespace OpenAPI\Server\Model; + +/** + * SampleModelToTestNamingConvention + */ +use Crell\Serde\Renaming\Cases; +use Crell\Serde\Attributes as Serde; + +#[Serde\ClassSettings(renameWith: Cases::snake_case)] +class SampleModelToTestNamingConvention +{ + /** + * + * + * @param string $propCamelCase + * + * + * @param string $PropPascalCase + * + * + * @param string $Prop_withRandomCase + */ + + public function __construct( + public string $propCamelCase = 'defaultName', + public string $PropPascalCase = 'DefaultName', + public string $Prop_withRandomCase = 'defaultName', + ) {} +} + diff --git a/samples/server/petstore/php-laravel-issue-21334/README.md b/samples/server/petstore/php-laravel-issue-21334/README.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/samples/server/petstore/php-laravel-issue-21334/composer.json b/samples/server/petstore/php-laravel-issue-21334/composer.json new file mode 100644 index 000000000000..6b230b67e52b --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/composer.json @@ -0,0 +1,31 @@ +{ + "name": "openapitools/petstore", + "description": "", + "keywords": [ + "openapi", + "php", + "sdk", + "api" + ], + "homepage": "https://openapi-generator.tech", + "license": "unlicense", + "authors": [ + { + "name": "OpenAPI", + "homepage": "https://openapi-generator.tech" + } + ], + "require": { + "php": "^8.1", + "laravel/framework": "^10.0", + "crell/serde": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "autoload": { + "psr-4": { + "OpenAPI\\Server\\" : "" + } + } +} diff --git a/samples/server/petstore/php-laravel-issue-21334/phpunit.xml.dist b/samples/server/petstore/php-laravel-issue-21334/phpunit.xml.dist new file mode 100644 index 000000000000..acb7d1807f5c --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/phpunit.xml.dist @@ -0,0 +1,21 @@ + + + + + ./Api + ./Model + ./Http/Controllers + . + + + + + + diff --git a/samples/server/petstore/php-laravel-issue-21334/routes.php b/samples/server/petstore/php-laravel-issue-21334/routes.php new file mode 100644 index 000000000000..21bd889e6f36 --- /dev/null +++ b/samples/server/petstore/php-laravel-issue-21334/routes.php @@ -0,0 +1,29 @@ + https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/php-laravel/ + */ + + +use Illuminate\Support\Facades\Route; + +/** + * GET getDummy + * Summary: + * Notes: + */ +Route::GET('/dummy', [\OpenAPI\Server\Http\Controllers\DefaultController::class, 'getDummy'])->name('default.get.dummy'); +