From aee7c15b0f28ec4d9e1acaaa9eebfe4f7ff06fdc Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 8 Jul 2024 18:29:24 +0530 Subject: [PATCH 01/18] Initial commit to create this PR --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1cd2090b..3bb79307 100644 --- a/README.md +++ b/README.md @@ -568,3 +568,4 @@ Professional support, consulting as well as software development services are av https://www.cebe.cc/en/contact Development of this library is sponsored by [cebe.:cloud: "Your Professional Deployment Platform"](https://cebe.cloud). + From 221f8acbca0b5f8a62ddc615c523b27a23234885 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 9 Jul 2024 20:46:19 +0530 Subject: [PATCH 02/18] Fix issue: `actionCreateinvoicePayment` instead of `actionCreateInvoicePayment` --- README.md | 1 - src/lib/generators/RestActionGenerator.php | 3 +- .../index.php | 13 +++ .../index.yaml | 84 +++++++++++++++++++ .../index.php | 2 +- .../index.php | 2 +- .../162_bug_dollarref_with_x_faker.php | 2 +- .../index.php | 2 +- .../index.php | 2 +- .../index.php | 2 +- tests/unit/IssueFixTest.php | 14 ++++ 11 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml diff --git a/README.md b/README.md index 3bb79307..1cd2090b 100644 --- a/README.md +++ b/README.md @@ -568,4 +568,3 @@ Professional support, consulting as well as software development services are av https://www.cebe.cc/en/contact Development of this library is sponsored by [cebe.:cloud: "Your Professional Deployment Platform"](https://cebe.cloud). - diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index daedd20f..4be6e6c7 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -109,9 +109,10 @@ protected function prepareAction(string $method, Operation $operation, RouteData } else { $controllerId = $routeData->controller; } + $action = ucfirst($routeData->action); return Yii::createObject(RestAction::class, [ [ - 'id' => trim("$actionType{$routeData->action}", '-'), + 'id' => trim("$actionType$action", '-'), 'controllerId' => $controllerId, 'urlPath' => $routeData->path, 'requestMethod' => strtoupper($method), diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.php new file mode 100644 index 00000000..d461ae44 --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.php @@ -0,0 +1,13 @@ + '@specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml', + 'generateUrls' => true, + 'generateModels' => false, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => true, + 'generateMigrations' => false, + 'generateModelFaker' => false, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` +]; diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml new file mode 100644 index 00000000..c11b1e9d --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml @@ -0,0 +1,84 @@ +openapi: 3.0.3 + +info: + title: 'Custom action name' + version: 1.0.0 + +tags: + - name: Payments + description: Pay or receive payments for your products from different channels + externalDocs: + description: Find out more + url: https://developer.adiuta.com/book/payments +paths: + /payments/invoice/{invoice}: + parameters: + - name: invoice + in: path + description: lorem ipsum + required: true + schema: + type: integer + post: + summary: Pay Invoice + description: Pay for Invoice with given invoice number + requestBody: + description: Record new payment for an invoice + content: + application/json: + schema: + $ref: '#/components/schemas/Payments' + required: true + responses: + '200': + description: Successfully paid the invoice + content: + application/json: + schema: + $ref: '#/components/schemas/Success' + + /payments/invoice-payment: + get: + operationId: opnid + summary: List + description: Lists + responses: + '200': + description: The Response + +components: + schemas: + Payments: + required: + - reference + - amount + - currency + properties: + invoice_number: + type: string + amount: + type: integer + format: int64 + currency: + type: string + + Success: + required: + - success + - message + properties: + success: + type: boolean + message: + type: string + + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/tests/specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/index.php b/tests/specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/index.php index 515b362c..70e43b74 100644 --- a/tests/specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/index.php +++ b/tests/specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/index.php @@ -9,6 +9,6 @@ ], 'generateControllers' => false, 'generateMigrations' => false, - 'generateModelFaker' => true, // `generateModels` must be `true` in orde to use `generateModelFaker` as `true` + 'generateModelFaker' => true, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` ]; diff --git a/tests/specs/issue_fix/159_bug_giiapi_generated_rules_emailid/index.php b/tests/specs/issue_fix/159_bug_giiapi_generated_rules_emailid/index.php index b66f036b..645671f2 100644 --- a/tests/specs/issue_fix/159_bug_giiapi_generated_rules_emailid/index.php +++ b/tests/specs/issue_fix/159_bug_giiapi_generated_rules_emailid/index.php @@ -9,6 +9,6 @@ ], 'generateControllers' => false, 'generateMigrations' => false, - 'generateModelFaker' => true, // `generateModels` must be `true` in orde to use `generateModelFaker` as `true` + 'generateModelFaker' => true, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` ]; diff --git a/tests/specs/issue_fix/162_bug_dollarref_with_x_faker/162_bug_dollarref_with_x_faker.php b/tests/specs/issue_fix/162_bug_dollarref_with_x_faker/162_bug_dollarref_with_x_faker.php index 19951cd4..8e6ca8d0 100644 --- a/tests/specs/issue_fix/162_bug_dollarref_with_x_faker/162_bug_dollarref_with_x_faker.php +++ b/tests/specs/issue_fix/162_bug_dollarref_with_x_faker/162_bug_dollarref_with_x_faker.php @@ -9,5 +9,5 @@ ], 'generateControllers' => false, 'generateMigrations' => false, - 'generateModelFaker' => true, // `generateModels` must be `true` in orde to use `generateModelFaker` as `true` + 'generateModelFaker' => true, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` ]; diff --git a/tests/specs/issue_fix/163_generator_crash_when_using_reference_inside_an_object/index.php b/tests/specs/issue_fix/163_generator_crash_when_using_reference_inside_an_object/index.php index 784db168..504db8f9 100644 --- a/tests/specs/issue_fix/163_generator_crash_when_using_reference_inside_an_object/index.php +++ b/tests/specs/issue_fix/163_generator_crash_when_using_reference_inside_an_object/index.php @@ -9,6 +9,6 @@ ], 'generateControllers' => true, 'generateMigrations' => true, - 'generateModelFaker' => true, // `generateModels` must be `true` in orde to use `generateModelFaker` as `true` + 'generateModelFaker' => true, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` ]; diff --git a/tests/specs/issue_fix/172_schemayaml_requestbody_has_no_effect/index.php b/tests/specs/issue_fix/172_schemayaml_requestbody_has_no_effect/index.php index 3debbb46..91969e28 100644 --- a/tests/specs/issue_fix/172_schemayaml_requestbody_has_no_effect/index.php +++ b/tests/specs/issue_fix/172_schemayaml_requestbody_has_no_effect/index.php @@ -9,6 +9,6 @@ ], 'generateControllers' => true, 'generateMigrations' => false, - 'generateModelFaker' => false, // `generateModels` must be `true` in orde to use `generateModelFaker` as `true` + 'generateModelFaker' => false, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` ]; diff --git a/tests/specs/issue_fix/175_bug_allof_with_multiple_dollarrefs/index.php b/tests/specs/issue_fix/175_bug_allof_with_multiple_dollarrefs/index.php index 3ccbc836..43e214b1 100644 --- a/tests/specs/issue_fix/175_bug_allof_with_multiple_dollarrefs/index.php +++ b/tests/specs/issue_fix/175_bug_allof_with_multiple_dollarrefs/index.php @@ -9,6 +9,6 @@ ], 'generateControllers' => true, 'generateMigrations' => true, - 'generateModelFaker' => true, // `generateModels` must be `true` in orde to use `generateModelFaker` as `true` + 'generateModelFaker' => true, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` ]; diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index b6c7abdb..5ccd5907 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -360,4 +360,18 @@ public function test158BugGiiapiGeneratedRulesEnumWithTrim() ]); $this->checkFiles($actualFiles, $expectedFiles); } + + // https://github.com/cebe/yii2-openapi/issues/144 + public function test144MethodsNamingForNonCrudActions() + { + $testFile = Yii::getAlias("@specs/issue_fix/144_methods_naming_for_non_crud_actions/index.php"); + $this->runGenerator($testFile); +// $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ +// 'recursive' => true, +// ]); +// $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/maria"), [ +// 'recursive' => true, +// ]); +// $this->checkFiles($actualFiles, $expectedFiles); + } } From 7799c8e3777dfdf6a87db6c34c4a2fc836f89307 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Wed, 10 Jul 2024 13:58:55 +0530 Subject: [PATCH 03/18] Fix issue in generated url rule config --- src/generator/default/urls.php | 8 +++++++- src/lib/generators/RestActionGenerator.php | 4 ++-- src/lib/items/RestAction.php | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/generator/default/urls.php b/src/generator/default/urls.php index e666a428..302ad533 100644 --- a/src/generator/default/urls.php +++ b/src/generator/default/urls.php @@ -1,3 +1,8 @@ + /** @@ -5,5 +10,6 @@ * * This file is auto generated. */ - + return ; diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index 4be6e6c7..90a0cf9b 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -109,10 +109,10 @@ protected function prepareAction(string $method, Operation $operation, RouteData } else { $controllerId = $routeData->controller; } - $action = ucfirst($routeData->action); + $action = Inflector::camel2id($routeData->action); return Yii::createObject(RestAction::class, [ [ - 'id' => trim("$actionType$action", '-'), + 'id' => trim("$actionType-$action", '-'), 'controllerId' => $controllerId, 'urlPath' => $routeData->path, 'requestMethod' => strtoupper($method), diff --git a/src/lib/items/RestAction.php b/src/lib/items/RestAction.php index 6852fafc..03a42a0c 100644 --- a/src/lib/items/RestAction.php +++ b/src/lib/items/RestAction.php @@ -72,9 +72,9 @@ public function getRoute():string { if ($this->prefix && !empty($this->prefixSettings)) { $prefix = $this->prefixSettings['module'] ?? $this->prefix; - return trim($prefix, '/').'/'.$this->controllerId.'/'.$this->id; + return trim($prefix, '/') . '/' . $this->controllerId . '/' . $this->id; } - return $this->controllerId.'/'.$this->id; + return $this->controllerId . '/' . $this->id; } public function getOptionsRoute():string From 5423164b78ceae04424094c2f0a06446b2283e50 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Thu, 11 Jul 2024 16:34:30 +0530 Subject: [PATCH 04/18] Fix this issue --- README.md | 5 +++ src/lib/CustomSpecAttr.php | 5 +++ src/lib/generators/RestActionGenerator.php | 8 ++++- .../app/config/urls.rest.php | 15 ++++++++ .../app/controllers/AbcController.php | 25 ++++++++++++++ .../app/controllers/PaymentController.php | 20 +++++++++++ .../app/controllers/PaymentsController.php | 20 +++++++++++ .../app/controllers/base/AbcController.php | 34 +++++++++++++++++++ .../controllers/base/PaymentController.php | 32 +++++++++++++++++ .../controllers/base/PaymentsController.php | 32 +++++++++++++++++ .../index.yaml | 19 ++++++++++- tests/unit/IssueFixTest.php | 14 ++++---- 12 files changed, 220 insertions(+), 9 deletions(-) create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/PaymentController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/PaymentsController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/AbcController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php diff --git a/README.md b/README.md index 1cd2090b..43089919 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,11 @@ Provide custom database table column name in case of relationship column. This w - x-fk-column-name: redelivery_of # this will create `redelivery_of` column instead of `redelivery_of_id` ``` +### `x-route` + +https://github.com/cebe/yii2-openapi/issues/144 +TODO + ## Many-to-Many relation definition There are two ways for define many-to-many relations: diff --git a/src/lib/CustomSpecAttr.php b/src/lib/CustomSpecAttr.php index 7e02a85d..1c87e4db 100644 --- a/src/lib/CustomSpecAttr.php +++ b/src/lib/CustomSpecAttr.php @@ -40,4 +40,9 @@ class CustomSpecAttr * Foreign key column name. See README for usage docs */ public const FK_COLUMN_NAME = 'x-fk-column-name'; + + /** + * Custom route (controller ID/action ID) instead of auto-generated. See README for usage docs. https://github.com/cebe/yii2-openapi/issues/144 + */ + public const ROUTE = 'x-route'; } diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index 90a0cf9b..27a78ce7 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -11,6 +11,7 @@ use cebe\openapi\spec\PathItem; use cebe\openapi\spec\Reference; use cebe\yii2openapi\lib\Config; +use cebe\yii2openapi\lib\CustomSpecAttr; use cebe\yii2openapi\lib\items\RestAction; use cebe\yii2openapi\lib\items\RouteData; use cebe\yii2openapi\lib\openapi\ResponseSchema; @@ -44,6 +45,11 @@ public function generate():array { $actions = []; foreach ($this->config->getOpenApi()->paths as $path => $pathItem) { + $customRoute = null; + if (isset($pathItem->{CustomSpecAttr::ROUTE})) { # https://github.com/cebe/yii2-openapi/issues/144 + $customRoute = $pathItem->{CustomSpecAttr::ROUTE}; + } + if ($path[0] !== '/') { throw new InvalidConfigException('Path must begin with /'); } @@ -53,7 +59,7 @@ public function generate():array if ($pathItem instanceof Reference) { $pathItem = $pathItem->resolve(); } - $actions[] = $this->resolvePath($path, $pathItem); + $actions[] = $this->resolvePath(!empty($customRoute) ? '/' . $customRoute : $path, $pathItem); } return array_merge(...$actions); } diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php new file mode 100644 index 00000000..c658232f --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php @@ -0,0 +1,15 @@ +' => 'payments/create-invoice', + 'GET payments/invoice-payment' => 'payment/invoice-payment', + 'GET abc/xyz' => 'abc/xyz', + 'POST abc/xyz' => 'abc/create-xyz', + 'payments/invoice/' => 'payments/options', + 'payments/invoice-payment' => 'payment/options', + 'abc/xyz' => 'abc/options', +]; diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php new file mode 100644 index 00000000..41621b8d --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php @@ -0,0 +1,25 @@ + [ + 'class' => \yii\rest\OptionsAction::class, + ], + ]; + } + + /** + * Checks the privilege of the current user. + * + * This method checks whether the current user has the privilege + * to run the specified action against the specified data model. + * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. + * + * @param string $action the ID of the action to be executed + * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param array $params additional parameters + * @throws \yii\web\ForbiddenHttpException if the user does not have access + */ + abstract public function checkAccess($action, $model = null, $params = []); + + abstract public function actionXyz(); + + abstract public function actionCreateXyz(); + +} diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentController.php new file mode 100644 index 00000000..4d39cdb8 --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentController.php @@ -0,0 +1,32 @@ + [ + 'class' => \yii\rest\OptionsAction::class, + ], + ]; + } + + /** + * Checks the privilege of the current user. + * + * This method checks whether the current user has the privilege + * to run the specified action against the specified data model. + * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. + * + * @param string $action the ID of the action to be executed + * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param array $params additional parameters + * @throws \yii\web\ForbiddenHttpException if the user does not have access + */ + abstract public function checkAccess($action, $model = null, $params = []); + + abstract public function actionInvoicePayment(); + +} diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php new file mode 100644 index 00000000..5fc9ac27 --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php @@ -0,0 +1,32 @@ + [ + 'class' => \yii\rest\OptionsAction::class, + ], + ]; + } + + /** + * Checks the privilege of the current user. + * + * This method checks whether the current user has the privilege + * to run the specified action against the specified data model. + * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. + * + * @param string $action the ID of the action to be executed + * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param array $params additional parameters + * @throws \yii\web\ForbiddenHttpException if the user does not have access + */ + abstract public function checkAccess($action, $model = null, $params = []); + + abstract public function actionCreateInvoice($invoice); + +} diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml index c11b1e9d..ee80b435 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: - title: 'Custom action name' + title: 'Custom route for path' version: 1.0.0 tags: @@ -46,6 +46,23 @@ paths: '200': description: The Response + /a1/b1: + x-route: 'abc/xyz' + get: + operationId: opnid5 + summary: List + description: Lists + responses: + '200': + description: The Response + post: + operationId: opnid23 + summary: List + description: Lists + responses: + '200': + description: The Response + components: schemas: Payments: diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 5ccd5907..1b3720cf 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -366,12 +366,12 @@ public function test144MethodsNamingForNonCrudActions() { $testFile = Yii::getAlias("@specs/issue_fix/144_methods_naming_for_non_crud_actions/index.php"); $this->runGenerator($testFile); -// $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ -// 'recursive' => true, -// ]); -// $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/maria"), [ -// 'recursive' => true, -// ]); -// $this->checkFiles($actualFiles, $expectedFiles); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/144_methods_naming_for_non_crud_actions/app"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); } } From 0521ec269a67a25014b0d03e8a479f2efcd6f3a8 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Thu, 11 Jul 2024 20:42:11 +0530 Subject: [PATCH 05/18] Fix bug - WIP --- src/lib/generators/ControllersGenerator.php | 14 +++++++------ src/lib/generators/RestActionGenerator.php | 20 ++++++++++++------- src/lib/items/RouteData.php | 1 + .../index.yaml | 14 ++++++++++++- tests/unit/IssueFixTest.php | 6 +++++- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/lib/generators/ControllersGenerator.php b/src/lib/generators/ControllersGenerator.php index 366f5532..bdea6e8c 100644 --- a/src/lib/generators/ControllersGenerator.php +++ b/src/lib/generators/ControllersGenerator.php @@ -129,12 +129,14 @@ protected function makeCustomController( $params = array_map(static function ($param) { return ['name' => $param]; }, $action->getParamNames()); - $reflection->addMethod( - $action->actionMethodName, - $params, - AbstractMemberGenerator::FLAG_PUBLIC, - '//TODO implement ' . $action->actionMethodName - ); + if (!$reflection->hasMethod($action->actionMethodName)) { + $reflection->addMethod( + $action->actionMethodName, + $params, + AbstractMemberGenerator::FLAG_PUBLIC, + '//TODO implement ' . $action->actionMethodName + ); + } } $classFileGenerator->setClasses([$reflection]); return $classFileGenerator; diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index 27a78ce7..c3b0f314 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -45,10 +45,6 @@ public function generate():array { $actions = []; foreach ($this->config->getOpenApi()->paths as $path => $pathItem) { - $customRoute = null; - if (isset($pathItem->{CustomSpecAttr::ROUTE})) { # https://github.com/cebe/yii2-openapi/issues/144 - $customRoute = $pathItem->{CustomSpecAttr::ROUTE}; - } if ($path[0] !== '/') { throw new InvalidConfigException('Path must begin with /'); @@ -59,7 +55,7 @@ public function generate():array if ($pathItem instanceof Reference) { $pathItem = $pathItem->resolve(); } - $actions[] = $this->resolvePath(!empty($customRoute) ? '/' . $customRoute : $path, $pathItem); + $actions[] = $this->resolvePath($path, $pathItem); } return array_merge(...$actions); } @@ -77,7 +73,11 @@ protected function resolvePath(string $path, PathItem $pathItem):array $routeData = Yii::createObject(RouteData::class, [$pathItem, $path, $this->config->urlPrefixes]); foreach ($pathItem->getOperations() as $method => $operation) { - $actions[] = $this->prepareAction($method, $operation, $routeData); + $customRoute = null; + if (isset($operation->{CustomSpecAttr::ROUTE})) { # https://github.com/cebe/yii2-openapi/issues/144 + $customRoute = $operation->{CustomSpecAttr::ROUTE}; + } + $actions[] = $this->prepareAction($method, $operation, $routeData, $customRoute); } return $actions; } @@ -90,7 +90,7 @@ protected function resolvePath(string $path, PathItem $pathItem):array * @throws \cebe\openapi\exceptions\UnresolvableReferenceException * @throws \yii\base\InvalidConfigException */ - protected function prepareAction(string $method, Operation $operation, RouteData $routeData):BaseObject + protected function prepareAction(string $method, Operation $operation, RouteData $routeData, $customRoute):BaseObject { $actionType = $this->resolveActionType($routeData, $method); $modelClass = ResponseSchema::guessModelClass($operation, $actionType); @@ -112,10 +112,16 @@ protected function prepareAction(string $method, Operation $operation, RouteData $controllerId = isset($this->config->controllerModelMap[$modelClass]) ? Inflector::camel2id($this->config->controllerModelMap[$modelClass]) : Inflector::camel2id($modelClass); + } elseif (!empty($customRoute)) { + $controllerId = explode('/', $customRoute)[0]; } else { $controllerId = $routeData->controller; } $action = Inflector::camel2id($routeData->action); + if (!empty($customRoute)) { + $actionType = ''; + $action = explode('/', $customRoute)[1]; + } return Yii::createObject(RestAction::class, [ [ 'id' => trim("$actionType-$action", '-'), diff --git a/src/lib/items/RouteData.php b/src/lib/items/RouteData.php index c426a517..48455835 100644 --- a/src/lib/items/RouteData.php +++ b/src/lib/items/RouteData.php @@ -166,6 +166,7 @@ final class RouteData extends BaseObject public function __construct(PathItem $pathItem, string $path, array $urlPrefixes = [], $config = []) { + // TODO url rules config php file should have path but not the x-route $this->path = $this->unprefixedPath = $path; $this->parts = explode('/', trim($path, '/')); $this->pathItem = $pathItem; diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml index ee80b435..4e299184 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml @@ -20,6 +20,7 @@ paths: schema: type: integer post: + x-route: 'payments/invoice' summary: Pay Invoice description: Pay for Invoice with given invoice number requestBody: @@ -47,8 +48,8 @@ paths: description: The Response /a1/b1: - x-route: 'abc/xyz' get: + x-route: 'abc/xyz' operationId: opnid5 summary: List description: Lists @@ -56,6 +57,7 @@ paths: '200': description: The Response post: + x-route: 'abc/xyz' operationId: opnid23 summary: List description: Lists @@ -63,6 +65,16 @@ paths: '200': description: The Response + /aa2/bb2: +# x-route: 'payment/xyz2' + get: + operationId: opnid7 + summary: List + description: Lists + responses: + '200': + description: The Response + components: schemas: Payments: diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 1b3720cf..977a0331 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -349,6 +349,10 @@ public function test159BugGiiapiGeneratedRulesEmailid() // https://github.com/cebe/yii2-openapi/issues/158 public function test158BugGiiapiGeneratedRulesEnumWithTrim() { + // TODO add more test case + // one new controller new action + // one new action in exiting controller + $this->changeDbToMariadb(); $testFile = Yii::getAlias("@specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/index.php"); $this->runGenerator($testFile, 'maria'); @@ -372,6 +376,6 @@ public function test144MethodsNamingForNonCrudActions() $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/144_methods_naming_for_non_crud_actions/app"), [ 'recursive' => true, ]); - $this->checkFiles($actualFiles, $expectedFiles); +// $this->checkFiles($actualFiles, $expectedFiles); // TODO } } From 53b3d80b6c5163da17c14c1293f272de04ecae25 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Thu, 11 Jul 2024 20:44:12 +0530 Subject: [PATCH 06/18] Fix failing test --- src/lib/generators/JsonActionGenerator.php | 2 +- src/lib/generators/RestActionGenerator.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/generators/JsonActionGenerator.php b/src/lib/generators/JsonActionGenerator.php index 696f7974..ff18a696 100644 --- a/src/lib/generators/JsonActionGenerator.php +++ b/src/lib/generators/JsonActionGenerator.php @@ -26,7 +26,7 @@ class JsonActionGenerator extends RestActionGenerator * @throws \yii\base\InvalidConfigException * @throws \cebe\openapi\exceptions\UnresolvableReferenceException */ - protected function prepareAction(string $method, Operation $operation, RouteData $routeData):BaseObject + protected function prepareAction(string $method, Operation $operation, RouteData $routeData, $customRoute = null):BaseObject { $actionType = $this->resolveActionType($routeData, $method); $modelClass = ResponseSchema::guessModelClass($operation, $actionType); diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index c3b0f314..07f16a84 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -90,7 +90,7 @@ protected function resolvePath(string $path, PathItem $pathItem):array * @throws \cebe\openapi\exceptions\UnresolvableReferenceException * @throws \yii\base\InvalidConfigException */ - protected function prepareAction(string $method, Operation $operation, RouteData $routeData, $customRoute):BaseObject + protected function prepareAction(string $method, Operation $operation, RouteData $routeData, $customRoute = null):BaseObject { $actionType = $this->resolveActionType($routeData, $method); $modelClass = ResponseSchema::guessModelClass($operation, $actionType); From b73b8993156455caf269cb2b8f427ce85d8c998d Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Fri, 12 Jul 2024 16:34:03 +0530 Subject: [PATCH 07/18] Fix style --- src/lib/generators/RestActionGenerator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index 07f16a84..933ff310 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -45,7 +45,6 @@ public function generate():array { $actions = []; foreach ($this->config->getOpenApi()->paths as $path => $pathItem) { - if ($path[0] !== '/') { throw new InvalidConfigException('Path must begin with /'); } From 7d64bc0500c44563709a03285259379162387eb9 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Fri, 12 Jul 2024 21:08:25 +0530 Subject: [PATCH 08/18] Fix bug --- src/lib/generators/JsonActionGenerator.php | 8 +++- src/lib/generators/RestActionGenerator.php | 8 +++- src/lib/items/RouteData.php | 1 - .../index.yaml | 45 ++++++++++++++++++- tests/unit/IssueFixTest.php | 4 -- 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/lib/generators/JsonActionGenerator.php b/src/lib/generators/JsonActionGenerator.php index ff18a696..3cc2de2a 100644 --- a/src/lib/generators/JsonActionGenerator.php +++ b/src/lib/generators/JsonActionGenerator.php @@ -26,8 +26,12 @@ class JsonActionGenerator extends RestActionGenerator * @throws \yii\base\InvalidConfigException * @throws \cebe\openapi\exceptions\UnresolvableReferenceException */ - protected function prepareAction(string $method, Operation $operation, RouteData $routeData, $customRoute = null):BaseObject - { + protected function prepareAction( + string $method, + Operation $operation, + RouteData $routeData, + ?string $customRoute = null + ): BaseObject { $actionType = $this->resolveActionType($routeData, $method); $modelClass = ResponseSchema::guessModelClass($operation, $actionType); $expectedRelations = in_array($actionType, ['list', 'view']) diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index 933ff310..d9fa2f68 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -89,8 +89,12 @@ protected function resolvePath(string $path, PathItem $pathItem):array * @throws \cebe\openapi\exceptions\UnresolvableReferenceException * @throws \yii\base\InvalidConfigException */ - protected function prepareAction(string $method, Operation $operation, RouteData $routeData, $customRoute = null):BaseObject - { + protected function prepareAction( + string $method, + Operation $operation, + RouteData $routeData, + ?string $customRoute = null + ): BaseObject { $actionType = $this->resolveActionType($routeData, $method); $modelClass = ResponseSchema::guessModelClass($operation, $actionType); $responseWrapper = ResponseSchema::findResponseWrapper($operation, $modelClass); diff --git a/src/lib/items/RouteData.php b/src/lib/items/RouteData.php index 48455835..c426a517 100644 --- a/src/lib/items/RouteData.php +++ b/src/lib/items/RouteData.php @@ -166,7 +166,6 @@ final class RouteData extends BaseObject public function __construct(PathItem $pathItem, string $path, array $urlPrefixes = [], $config = []) { - // TODO url rules config php file should have path but not the x-route $this->path = $this->unprefixedPath = $path; $this->parts = explode('/', trim($path, '/')); $this->pathItem = $pathItem; diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml index 4e299184..4641aefc 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml @@ -11,6 +11,49 @@ tags: description: Find out more url: https://developer.adiuta.com/book/payments paths: + /fruit/mango: + get: + x-route: fruits/mango + operationId: opnid9 + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + + + /fruits/mango: + get: + operationId: opnid8 + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + post: + operationId: opnid9 + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + + /animal/goat: + get: + operationId: opnid8 + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + post: + operationId: opnid9 + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + /payments/invoice/{invoice}: parameters: - name: invoice @@ -66,8 +109,8 @@ paths: description: The Response /aa2/bb2: -# x-route: 'payment/xyz2' get: + x-route: 'payments/xyz2' operationId: opnid7 summary: List description: Lists diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 977a0331..6d1df0c7 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -349,10 +349,6 @@ public function test159BugGiiapiGeneratedRulesEmailid() // https://github.com/cebe/yii2-openapi/issues/158 public function test158BugGiiapiGeneratedRulesEnumWithTrim() { - // TODO add more test case - // one new controller new action - // one new action in exiting controller - $this->changeDbToMariadb(); $testFile = Yii::getAlias("@specs/issue_fix/158_bug_giiapi_generated_rules_enum_with_trim/index.php"); $this->runGenerator($testFile, 'maria'); From 8e5f52b8451c20e483c7dfeb09a71d497e423a77 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Fri, 12 Jul 2024 21:11:57 +0530 Subject: [PATCH 09/18] Add more tests --- .../app/config/urls.rest.php | 18 +++++++--- .../app/controllers/AbcController.php | 5 --- .../app/controllers/AnimalController.php | 25 ++++++++++++++ .../app/controllers/FruitController.php | 25 ++++++++++++++ .../app/controllers/FruitsController.php | 20 +++++++++++ .../app/controllers/PaymentsController.php | 9 +++-- .../app/controllers/base/AbcController.php | 2 +- .../app/controllers/base/AnimalController.php | 34 +++++++++++++++++++ .../app/controllers/base/FruitController.php | 34 +++++++++++++++++++ .../app/controllers/base/FruitsController.php | 32 +++++++++++++++++ .../controllers/base/PaymentsController.php | 4 ++- tests/unit/IssueFixTest.php | 2 +- 12 files changed, 196 insertions(+), 14 deletions(-) create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AnimalController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/FruitController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/FruitsController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/AnimalController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitController.php create mode 100644 tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitsController.php diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php index c658232f..1d39a048 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/config/urls.rest.php @@ -5,11 +5,21 @@ * This file is auto generated. */ return [ - 'POST payments/invoice/' => 'payments/create-invoice', + 'GET fruit/mango' => 'fruits/mango', + 'GET fruits/mango' => 'fruit/mango', + 'POST fruits/mango' => 'fruit/create-mango', + 'GET animal/goat' => 'animal/goat', + 'POST animal/goat' => 'animal/create-goat', + 'POST payments/invoice/' => 'payments/invoice', 'GET payments/invoice-payment' => 'payment/invoice-payment', - 'GET abc/xyz' => 'abc/xyz', - 'POST abc/xyz' => 'abc/create-xyz', + 'GET a1/b1' => 'abc/xyz', + 'POST a1/b1' => 'abc/xyz', + 'GET aa2/bb2' => 'payments/xyz2', + 'fruit/mango' => 'fruits/options', + 'fruits/mango' => 'fruit/options', + 'animal/goat' => 'animal/options', 'payments/invoice/' => 'payments/options', 'payments/invoice-payment' => 'payment/options', - 'abc/xyz' => 'abc/options', + 'a1/b1' => 'abc/options', + 'aa2/bb2' => 'payments/options', ]; diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php index 41621b8d..833d931e 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AbcController.php @@ -15,11 +15,6 @@ public function actionXyz() //TODO implement actionXyz } - public function actionCreateXyz() - { - //TODO implement actionCreateXyz - } - } diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AnimalController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AnimalController.php new file mode 100644 index 00000000..27b00d8b --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/AnimalController.php @@ -0,0 +1,25 @@ + [ + 'class' => \yii\rest\OptionsAction::class, + ], + ]; + } + + /** + * Checks the privilege of the current user. + * + * This method checks whether the current user has the privilege + * to run the specified action against the specified data model. + * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. + * + * @param string $action the ID of the action to be executed + * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param array $params additional parameters + * @throws \yii\web\ForbiddenHttpException if the user does not have access + */ + abstract public function checkAccess($action, $model = null, $params = []); + + abstract public function actionGoat(); + + abstract public function actionCreateGoat(); + +} diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitController.php new file mode 100644 index 00000000..5cef0ed5 --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitController.php @@ -0,0 +1,34 @@ + [ + 'class' => \yii\rest\OptionsAction::class, + ], + ]; + } + + /** + * Checks the privilege of the current user. + * + * This method checks whether the current user has the privilege + * to run the specified action against the specified data model. + * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. + * + * @param string $action the ID of the action to be executed + * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param array $params additional parameters + * @throws \yii\web\ForbiddenHttpException if the user does not have access + */ + abstract public function checkAccess($action, $model = null, $params = []); + + abstract public function actionMango(); + + abstract public function actionCreateMango(); + +} diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitsController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitsController.php new file mode 100644 index 00000000..01549012 --- /dev/null +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/FruitsController.php @@ -0,0 +1,32 @@ + [ + 'class' => \yii\rest\OptionsAction::class, + ], + ]; + } + + /** + * Checks the privilege of the current user. + * + * This method checks whether the current user has the privilege + * to run the specified action against the specified data model. + * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. + * + * @param string $action the ID of the action to be executed + * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param array $params additional parameters + * @throws \yii\web\ForbiddenHttpException if the user does not have access + */ + abstract public function checkAccess($action, $model = null, $params = []); + + abstract public function actionMango(); + +} diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php index 5fc9ac27..869d64e6 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/PaymentsController.php @@ -27,6 +27,8 @@ public function actions() */ abstract public function checkAccess($action, $model = null, $params = []); - abstract public function actionCreateInvoice($invoice); + abstract public function actionInvoice($invoice); + + abstract public function actionXyz2(); } diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 6d1df0c7..1b3720cf 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -372,6 +372,6 @@ public function test144MethodsNamingForNonCrudActions() $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/144_methods_naming_for_non_crud_actions/app"), [ 'recursive' => true, ]); -// $this->checkFiles($actualFiles, $expectedFiles); // TODO + $this->checkFiles($actualFiles, $expectedFiles); } } From 136cea80d65d71d3bf59343602626295a2106f61 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Sat, 13 Jul 2024 15:02:59 +0530 Subject: [PATCH 10/18] Add docs --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 43089919..f49afb8e 100644 --- a/README.md +++ b/README.md @@ -311,8 +311,64 @@ Provide custom database table column name in case of relationship column. This w ### `x-route` -https://github.com/cebe/yii2-openapi/issues/144 -TODO +To customize route (controller ID/action ID) for a path, use custom key `x-route` with value `/`. It can be used for non-crud paths. It must be used under HTTP method key but not +directly under the `paths` key of OpenAPI spec. Example: + +```yaml +paths: + /payments/invoice/{invoice}: + parameters: + - name: invoice + in: path + description: lorem ipsum + required: true + schema: + type: integer + post: + x-route: 'payments/invoice' + summary: Pay Invoice + description: Pay for Invoice with given invoice number + requestBody: + description: Record new payment for an invoice + content: + application/json: + schema: + $ref: '#/components/schemas/Payments' + required: true + responses: + '200': + description: Successfully paid the invoice + content: + application/json: + schema: + $ref: '#/components/schemas/Success' +``` + +It won't generate `actionCreateInvoice` in `PaymentsController.php` file, but will generate `actionInvoice` instead in +same file. + +Also, if same action is needed for HTTP GET and POST then use same value for `x-route`. Example: + +```yaml +paths: + /a1/b1: + get: + x-route: 'abc/xyz' + operationId: opnid1 + summary: List + description: Lists + responses: + '200': + description: The Response + post: + x-route: 'abc/xyz' + operationId: opnid2 + summary: create + description: create + responses: + '200': + description: The Response +``` ## Many-to-Many relation definition From 528497d9e3adf25aabe8e287c3a76a9450660311 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Sat, 13 Jul 2024 15:10:21 +0530 Subject: [PATCH 11/18] Add docs about URL rules config --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index f49afb8e..f6bebf7b 100644 --- a/README.md +++ b/README.md @@ -347,6 +347,12 @@ paths: It won't generate `actionCreateInvoice` in `PaymentsController.php` file, but will generate `actionInvoice` instead in same file. +Generated URL rules config for above is (in `urls.rest.php` or pertinent file): +```php + 'POST payments/invoice/' => 'payments/invoice', + 'payments/invoice/' => 'payments/options', +``` + Also, if same action is needed for HTTP GET and POST then use same value for `x-route`. Example: ```yaml @@ -370,6 +376,13 @@ paths: description: The Response ``` +Generated URL rules config for above is (in `urls.rest.php` or pertinent file): +```php + 'GET a1/b1' => 'abc/xyz', + 'POST a1/b1' => 'abc/xyz', + 'a1/b1' => 'abc/options', +``` + ## Many-to-Many relation definition There are two ways for define many-to-many relations: From fcf41473e4d085cc6175ec18a4761a12e1c52b03 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 16 Jul 2024 19:53:39 +0530 Subject: [PATCH 12/18] Add fix & test for https://github.com/cebe/yii2-openapi/issues/84 --- src/generator/ApiGenerator.php | 27 +++++++ src/lib/generators/ControllersGenerator.php | 15 ++-- src/lib/generators/RestActionGenerator.php | 15 +++- src/lib/items/RestAction.php | 13 ++++ .../index.yaml | 6 +- .../index.php | 13 ++++ .../index.yaml | 77 +++++++++++++++++++ tests/unit/IssueFixTest.php | 14 ++++ 8 files changed, 168 insertions(+), 12 deletions(-) create mode 100644 tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.php create mode 100644 tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml diff --git a/src/generator/ApiGenerator.php b/src/generator/ApiGenerator.php index f930f949..14fdbed0 100644 --- a/src/generator/ApiGenerator.php +++ b/src/generator/ApiGenerator.php @@ -7,6 +7,7 @@ namespace cebe\yii2openapi\generator; +use cebe\yii2openapi\lib\items\RestAction; use yii\db\mysql\Schema as MySqlSchema; use SamIT\Yii2\MariaDb\Schema as MariaDbSchema; use yii\db\pgsql\Schema as PgSqlSchema; @@ -473,6 +474,7 @@ public function generate():array $urlRulesGenerator = Yii::createObject(UrlRulesGenerator::class, [$config, $actions]); $files = $urlRulesGenerator->generate(); + $actions = static::removeDuplicateActions($actions); $controllersGenerator = Yii::createObject(ControllersGenerator::class, [$config, $actions]); $files->merge($controllersGenerator->generate()); @@ -521,4 +523,29 @@ public static function isMariaDb():bool { return strpos(Yii::$app->db->schema->getServerVersion(), 'MariaDB') !== false; } + + /** + * @param RestAction[] $actions + * @return RestAction[] + * https://github.com/cebe/yii2-openapi/issues/84 + */ + public static function removeDuplicateActions(array $actions): array + { + $actions = array_filter($actions, function (RestAction $action) { + if ($action->isDuplicate) { + return false; + } + return true; + }); + + $actions = array_map(function (RestAction $action) { + if ($action->isOriginalForCustomRoute) { + $action->idParam = null; + $action->params = []; + } + return $action; + }, $actions); + + return $actions; + } } diff --git a/src/lib/generators/ControllersGenerator.php b/src/lib/generators/ControllersGenerator.php index bdea6e8c..bd749c9f 100644 --- a/src/lib/generators/ControllersGenerator.php +++ b/src/lib/generators/ControllersGenerator.php @@ -129,14 +129,13 @@ protected function makeCustomController( $params = array_map(static function ($param) { return ['name' => $param]; }, $action->getParamNames()); - if (!$reflection->hasMethod($action->actionMethodName)) { - $reflection->addMethod( - $action->actionMethodName, - $params, - AbstractMemberGenerator::FLAG_PUBLIC, - '//TODO implement ' . $action->actionMethodName - ); - } + + $reflection->addMethod( + $action->actionMethodName, + $params, + AbstractMemberGenerator::FLAG_PUBLIC, + '//TODO implement ' . $action->actionMethodName + ); } $classFileGenerator->setClasses([$reflection]); return $classFileGenerator; diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index d9fa2f68..d05f342a 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -59,6 +59,7 @@ public function generate():array return array_merge(...$actions); } + private $allCustomRoutes = []; /** * @param string $path * @param \cebe\openapi\spec\PathItem $pathItem @@ -76,7 +77,19 @@ protected function resolvePath(string $path, PathItem $pathItem):array if (isset($operation->{CustomSpecAttr::ROUTE})) { # https://github.com/cebe/yii2-openapi/issues/144 $customRoute = $operation->{CustomSpecAttr::ROUTE}; } - $actions[] = $this->prepareAction($method, $operation, $routeData, $customRoute); + if ($customRoute === null) { + $actions[] = $this->prepareAction($method, $operation, $routeData, $customRoute); + } else { + // TODO rename + $actionHere = $this->prepareAction($method, $operation, $routeData, $customRoute); + $actionHere->isOriginalForCustomRoute = true; + if (!in_array($customRoute, $this->allCustomRoutes)) { + $actionHere->isOriginalForCustomRoute = false; + $actionHere->isDuplicate = true; + $this->allCustomRoutes[] = $customRoute; + } + $actions[] = $actionHere; + } } return $actions; } diff --git a/src/lib/items/RestAction.php b/src/lib/items/RestAction.php index 03a42a0c..cd97abd3 100644 --- a/src/lib/items/RestAction.php +++ b/src/lib/items/RestAction.php @@ -68,6 +68,19 @@ final class RestAction extends BaseObject */ public $responseWrapper; + /** + * @var bool + * @see $isDuplicate + */ + public $isOriginalForCustomRoute = false; + /** + * @var bool + * https://github.com/cebe/yii2-openapi/issues/84 + * Generate only one action for paths like: `GET /calendar/domains` and `GET /calendar/domains/{id}`. + * @see $isOriginalForCustomRoute + */ + public $isDuplicate = false; + public function getRoute():string { if ($this->prefix && !empty($this->prefixSettings)) { diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml index 4641aefc..43435cc4 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/index.yaml @@ -14,7 +14,7 @@ paths: /fruit/mango: get: x-route: fruits/mango - operationId: opnid9 + operationId: opnid91 summary: Lorem ipsum description: Lorem ipsum description responses: @@ -24,7 +24,7 @@ paths: /fruits/mango: get: - operationId: opnid8 + operationId: opnid81 summary: Lorem ipsum description: Lorem ipsum description responses: @@ -47,7 +47,7 @@ paths: '200': description: The Response post: - operationId: opnid9 + operationId: opnid92 summary: Lorem ipsum description: Lorem ipsum description responses: diff --git a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.php b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.php new file mode 100644 index 00000000..6d88068a --- /dev/null +++ b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.php @@ -0,0 +1,13 @@ + '@specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml', + 'generateUrls' => true, + 'generateModels' => false, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => true, + 'generateMigrations' => false, + 'generateModelFaker' => false, // `generateModels` must be `true` in order to use `generateModelFaker` as `true` +]; diff --git a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml new file mode 100644 index 00000000..7cbbdbf9 --- /dev/null +++ b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml @@ -0,0 +1,77 @@ +openapi: 3.0.3 + +info: + title: 'Custom route for path' + version: 1.0.0 + +tags: + - name: Payments + description: Pay or receive payments for your products from different channels + externalDocs: + description: Find out more + url: https://developer.adiuta.com/book/payments +paths: + /calendar/domains: + get: + x-route: calendar/domains + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + + + /calendar/domains/{id}: + parameters: + - name: id + in: path + description: lorem ipsum + required: true + schema: + type: integer + get: + x-route: calendar/domains + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + + + +components: + schemas: + Payments: + required: + - reference + - amount + - currency + properties: + invoice_number: + type: string + amount: + type: integer + format: int64 + currency: + type: string + + Success: + required: + - success + - message + properties: + success: + type: boolean + message: + type: string + + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 1b3720cf..040d5ff7 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -374,4 +374,18 @@ public function test144MethodsNamingForNonCrudActions() ]); $this->checkFiles($actualFiles, $expectedFiles); } + + // https://github.com/cebe/yii2-openapi/issues/84 + public function test84HowToGenerateControllerCodeWithDistinctMethodNamesInCaseOfPrefixInPaths() + { + $testFile = Yii::getAlias("@specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.php"); + $this->runGenerator($testFile); + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app"), [ + 'recursive' => true, + ]); +// $this->checkFiles($actualFiles, $expectedFiles); // TODO + } } From 60d0b1edb17d74d3860d2afae60310fe3ce01f2b Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 16 Jul 2024 20:30:37 +0530 Subject: [PATCH 13/18] Fix failing tests --- src/generator/ApiGenerator.php | 22 ++++++++++--------- src/lib/generators/RestActionGenerator.php | 17 +++++++------- .../app/controllers/base/AbcController.php | 2 -- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/generator/ApiGenerator.php b/src/generator/ApiGenerator.php index 14fdbed0..f31efb4c 100644 --- a/src/generator/ApiGenerator.php +++ b/src/generator/ApiGenerator.php @@ -7,10 +7,6 @@ namespace cebe\yii2openapi\generator; -use cebe\yii2openapi\lib\items\RestAction; -use yii\db\mysql\Schema as MySqlSchema; -use SamIT\Yii2\MariaDb\Schema as MariaDbSchema; -use yii\db\pgsql\Schema as PgSqlSchema; use cebe\openapi\Reader; use cebe\openapi\spec\OpenApi; use cebe\yii2openapi\lib\Config; @@ -21,9 +17,13 @@ use cebe\yii2openapi\lib\generators\RestActionGenerator; use cebe\yii2openapi\lib\generators\TransformersGenerator; use cebe\yii2openapi\lib\generators\UrlRulesGenerator; +use cebe\yii2openapi\lib\items\FractalAction; +use cebe\yii2openapi\lib\items\RestAction; use cebe\yii2openapi\lib\PathAutoCompletion; use cebe\yii2openapi\lib\SchemaToDatabase; use Yii; +use yii\db\mysql\Schema as MySqlSchema; +use yii\db\pgsql\Schema as PgSqlSchema; use yii\gii\CodeFile; use yii\gii\Generator; use yii\helpers\Html; @@ -525,21 +525,23 @@ public static function isMariaDb():bool } /** - * @param RestAction[] $actions - * @return RestAction[] + * @param RestAction[]|FractalAction[] $actions + * @return RestAction[]|FractalAction[] * https://github.com/cebe/yii2-openapi/issues/84 */ public static function removeDuplicateActions(array $actions): array { - $actions = array_filter($actions, function (RestAction $action) { - if ($action->isDuplicate) { + $actions = array_filter($actions, function ($action) { + /** @var $action RestAction|FractalAction */ + if ($action instanceof RestAction && $action->isDuplicate) { return false; } return true; }); - $actions = array_map(function (RestAction $action) { - if ($action->isOriginalForCustomRoute) { + $actions = array_map(function ($action) { + /** @var $action RestAction|FractalAction */ + if ($action instanceof RestAction && $action->isOriginalForCustomRoute) { $action->idParam = null; $action->params = []; } diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index d05f342a..8efd2138 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -77,19 +77,18 @@ protected function resolvePath(string $path, PathItem $pathItem):array if (isset($operation->{CustomSpecAttr::ROUTE})) { # https://github.com/cebe/yii2-openapi/issues/144 $customRoute = $operation->{CustomSpecAttr::ROUTE}; } - if ($customRoute === null) { - $actions[] = $this->prepareAction($method, $operation, $routeData, $customRoute); - } else { - // TODO rename - $actionHere = $this->prepareAction($method, $operation, $routeData, $customRoute); - $actionHere->isOriginalForCustomRoute = true; - if (!in_array($customRoute, $this->allCustomRoutes)) { - $actionHere->isOriginalForCustomRoute = false; + + // TODO rename + $actionHere = $this->prepareAction($method, $operation, $routeData, $customRoute); + if ($customRoute !== null) { + if (in_array($customRoute, $this->allCustomRoutes)) { $actionHere->isDuplicate = true; + } else { + $actionHere->isDuplicate = false; $this->allCustomRoutes[] = $customRoute; } - $actions[] = $actionHere; } + $actions[] = $actionHere; } return $actions; } diff --git a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/AbcController.php b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/AbcController.php index 5fb7d836..4786e4ae 100644 --- a/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/AbcController.php +++ b/tests/specs/issue_fix/144_methods_naming_for_non_crud_actions/app/controllers/base/AbcController.php @@ -29,6 +29,4 @@ abstract public function checkAccess($action, $model = null, $params = []); abstract public function actionXyz(); - abstract public function actionXyz(); - } From 8dd401b19d29551fb3612c377b2126049edf3fc0 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 16 Jul 2024 20:32:31 +0530 Subject: [PATCH 14/18] Complete the test --- .../app/config/urls.rest.php | 12 +++++++ .../app/controllers/CalendarController.php | 20 ++++++++++++ .../controllers/base/CalendarController.php | 32 +++++++++++++++++++ tests/unit/IssueFixTest.php | 2 +- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php create mode 100644 tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/controllers/CalendarController.php create mode 100644 tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/controllers/base/CalendarController.php diff --git a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php new file mode 100644 index 00000000..04937d8d --- /dev/null +++ b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php @@ -0,0 +1,12 @@ + 'calendar/domains', + 'GET calendar/domains/' => 'calendar/domains', + 'calendar/domains' => 'calendar/options', + 'calendar/domains/' => 'calendar/options', +]; diff --git a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/controllers/CalendarController.php b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/controllers/CalendarController.php new file mode 100644 index 00000000..7096a165 --- /dev/null +++ b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/controllers/CalendarController.php @@ -0,0 +1,20 @@ + [ + 'class' => \yii\rest\OptionsAction::class, + ], + ]; + } + + /** + * Checks the privilege of the current user. + * + * This method checks whether the current user has the privilege + * to run the specified action against the specified data model. + * If the user does not have access, a [[ForbiddenHttpException]] should be thrown. + * + * @param string $action the ID of the action to be executed + * @param object $model the model to be accessed. If null, it means no specific model is being accessed. + * @param array $params additional parameters + * @throws \yii\web\ForbiddenHttpException if the user does not have access + */ + abstract public function checkAccess($action, $model = null, $params = []); + + abstract public function actionDomains(); + +} diff --git a/tests/unit/IssueFixTest.php b/tests/unit/IssueFixTest.php index 040d5ff7..5daf9786 100644 --- a/tests/unit/IssueFixTest.php +++ b/tests/unit/IssueFixTest.php @@ -386,6 +386,6 @@ public function test84HowToGenerateControllerCodeWithDistinctMethodNamesInCaseOf $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app"), [ 'recursive' => true, ]); -// $this->checkFiles($actualFiles, $expectedFiles); // TODO + $this->checkFiles($actualFiles, $expectedFiles); } } From 2816f28092982f49b3f33bf29b9a42667c447d77 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 16 Jul 2024 20:40:54 +0530 Subject: [PATCH 15/18] Add more concrete tests --- src/lib/generators/RestActionGenerator.php | 7 ++++-- .../app/config/urls.rest.php | 2 ++ .../index.yaml | 22 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index 8efd2138..bd690467 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -81,11 +81,14 @@ protected function resolvePath(string $path, PathItem $pathItem):array // TODO rename $actionHere = $this->prepareAction($method, $operation, $routeData, $customRoute); if ($customRoute !== null) { - if (in_array($customRoute, $this->allCustomRoutes)) { + if (in_array($customRoute, array_keys($this->allCustomRoutes))) { $actionHere->isDuplicate = true; + if ($actionHere->params !== $this->allCustomRoutes[$customRoute]) { + $this->allCustomRoutes[$customRoute]->isOriginalForCustomRoute = true; + } } else { $actionHere->isDuplicate = false; - $this->allCustomRoutes[] = $customRoute; + $this->allCustomRoutes[$customRoute] = $actionHere; } } $actions[] = $actionHere; diff --git a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php index 04937d8d..9bb87c11 100644 --- a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php +++ b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/app/config/urls.rest.php @@ -7,6 +7,8 @@ return [ 'GET calendar/domains' => 'calendar/domains', 'GET calendar/domains/' => 'calendar/domains', + 'GET calendar/domains//' => 'calendar/domains', 'calendar/domains' => 'calendar/options', 'calendar/domains/' => 'calendar/options', + 'calendar/domains//' => 'calendar/options', ]; diff --git a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml index 7cbbdbf9..681ae664 100644 --- a/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml +++ b/tests/specs/issue_fix/84_how_to_generate_controller_code_with_distinct_method_names_in_case_of_prefix_in_paths/index.yaml @@ -37,6 +37,28 @@ paths: '200': description: The Response + /calendar/domains/{id}/{id2}: + parameters: + - name: id + in: path + description: lorem ipsum + required: true + schema: + type: integer + - name: id2 + in: path + description: lorem ipsum + required: true + schema: + type: integer + get: + x-route: calendar/domains + summary: Lorem ipsum + description: Lorem ipsum description + responses: + '200': + description: The Response + components: From f37e45e0d21daa8b4685f4417d9ced0749f9895a Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 16 Jul 2024 20:57:44 +0530 Subject: [PATCH 16/18] Refactor and add docs --- README.md | 1 + src/generator/ApiGenerator.php | 2 +- src/lib/generators/RestActionGenerator.php | 12 ++++++------ src/lib/items/RestAction.php | 8 +++++++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f6bebf7b..7eeb62ce 100644 --- a/README.md +++ b/README.md @@ -382,6 +382,7 @@ Generated URL rules config for above is (in `urls.rest.php` or pertinent file): 'POST a1/b1' => 'abc/xyz', 'a1/b1' => 'abc/options', ``` +`x-route` does not support [Yii Modules](https://www.yiiframework.com/doc/guide/2.0/en/structure-modules). ## Many-to-Many relation definition diff --git a/src/generator/ApiGenerator.php b/src/generator/ApiGenerator.php index f31efb4c..5a1f83c5 100644 --- a/src/generator/ApiGenerator.php +++ b/src/generator/ApiGenerator.php @@ -474,7 +474,7 @@ public function generate():array $urlRulesGenerator = Yii::createObject(UrlRulesGenerator::class, [$config, $actions]); $files = $urlRulesGenerator->generate(); - $actions = static::removeDuplicateActions($actions); + $actions = static::removeDuplicateActions($actions); // in case of non-crud actions having custom route `x-route` set $controllersGenerator = Yii::createObject(ControllersGenerator::class, [$config, $actions]); $files->merge($controllersGenerator->generate()); diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index bd690467..9796be02 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -79,19 +79,19 @@ protected function resolvePath(string $path, PathItem $pathItem):array } // TODO rename - $actionHere = $this->prepareAction($method, $operation, $routeData, $customRoute); + $action = $this->prepareAction($method, $operation, $routeData, $customRoute); if ($customRoute !== null) { if (in_array($customRoute, array_keys($this->allCustomRoutes))) { - $actionHere->isDuplicate = true; - if ($actionHere->params !== $this->allCustomRoutes[$customRoute]) { + $action->isDuplicate = true; + if ($action->params !== $this->allCustomRoutes[$customRoute]) { $this->allCustomRoutes[$customRoute]->isOriginalForCustomRoute = true; } } else { - $actionHere->isDuplicate = false; - $this->allCustomRoutes[$customRoute] = $actionHere; + $action->isDuplicate = false; + $this->allCustomRoutes[$customRoute] = $action; } } - $actions[] = $actionHere; + $actions[] = $action; } return $actions; } diff --git a/src/lib/items/RestAction.php b/src/lib/items/RestAction.php index cd97abd3..fc82712f 100644 --- a/src/lib/items/RestAction.php +++ b/src/lib/items/RestAction.php @@ -71,13 +71,19 @@ final class RestAction extends BaseObject /** * @var bool * @see $isDuplicate + * https://github.com/cebe/yii2-openapi/issues/84 + * see `x-route` in README.md + * Used for generating only one action for paths like: `GET /calendar/domains` and `GET /calendar/domains/{id}` given that they have same `x-route`. + * This is used to flag first of one or more duplicates */ public $isOriginalForCustomRoute = false; + /** * @var bool * https://github.com/cebe/yii2-openapi/issues/84 - * Generate only one action for paths like: `GET /calendar/domains` and `GET /calendar/domains/{id}`. + * Generate only one action for paths like: `GET /calendar/domains` and `GET /calendar/domains/{id}` given that they have same `x-route`. * @see $isOriginalForCustomRoute + * see `x-route` in README.md */ public $isDuplicate = false; From 8c764965a1a4fef16ac1124aa508e5a2c33ff862 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Fri, 26 Jul 2024 17:25:19 +0530 Subject: [PATCH 17/18] Remove TODO --- src/lib/generators/RestActionGenerator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index 9796be02..ba8920ec 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -78,7 +78,6 @@ protected function resolvePath(string $path, PathItem $pathItem):array $customRoute = $operation->{CustomSpecAttr::ROUTE}; } - // TODO rename $action = $this->prepareAction($method, $operation, $routeData, $customRoute); if ($customRoute !== null) { if (in_array($customRoute, array_keys($this->allCustomRoutes))) { From 5f7e9932872b6ed4427d91803fdb777279bd95d8 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Fri, 26 Jul 2024 18:37:18 +0530 Subject: [PATCH 18/18] Refactor --- src/generator/ApiGenerator.php | 2 +- src/lib/generators/RestActionGenerator.php | 4 ++-- src/lib/items/RestAction.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/generator/ApiGenerator.php b/src/generator/ApiGenerator.php index 5a1f83c5..fe135c5d 100644 --- a/src/generator/ApiGenerator.php +++ b/src/generator/ApiGenerator.php @@ -541,7 +541,7 @@ public static function removeDuplicateActions(array $actions): array $actions = array_map(function ($action) { /** @var $action RestAction|FractalAction */ - if ($action instanceof RestAction && $action->isOriginalForCustomRoute) { + if ($action instanceof RestAction && $action->zeroParams) { $action->idParam = null; $action->params = []; } diff --git a/src/lib/generators/RestActionGenerator.php b/src/lib/generators/RestActionGenerator.php index ba8920ec..b8d5998c 100644 --- a/src/lib/generators/RestActionGenerator.php +++ b/src/lib/generators/RestActionGenerator.php @@ -82,8 +82,8 @@ protected function resolvePath(string $path, PathItem $pathItem):array if ($customRoute !== null) { if (in_array($customRoute, array_keys($this->allCustomRoutes))) { $action->isDuplicate = true; - if ($action->params !== $this->allCustomRoutes[$customRoute]) { - $this->allCustomRoutes[$customRoute]->isOriginalForCustomRoute = true; + if ($action->params !== $this->allCustomRoutes[$customRoute]->params) { + $this->allCustomRoutes[$customRoute]->zeroParams = true; } } else { $action->isDuplicate = false; diff --git a/src/lib/items/RestAction.php b/src/lib/items/RestAction.php index fc82712f..5192997a 100644 --- a/src/lib/items/RestAction.php +++ b/src/lib/items/RestAction.php @@ -74,15 +74,15 @@ final class RestAction extends BaseObject * https://github.com/cebe/yii2-openapi/issues/84 * see `x-route` in README.md * Used for generating only one action for paths like: `GET /calendar/domains` and `GET /calendar/domains/{id}` given that they have same `x-route`. - * This is used to flag first of one or more duplicates + * If duplicates routes have same params then `false`, else action is generated with no (0) params `true` */ - public $isOriginalForCustomRoute = false; + public $zeroParams = false; /** * @var bool * https://github.com/cebe/yii2-openapi/issues/84 * Generate only one action for paths like: `GET /calendar/domains` and `GET /calendar/domains/{id}` given that they have same `x-route`. - * @see $isOriginalForCustomRoute + * @see $zeroParams * see `x-route` in README.md */ public $isDuplicate = false;