From 53af5c970fbdc7d74ad039ed0c6116bb55b3a71a Mon Sep 17 00:00:00 2001 From: Touhidur Rahman Date: Sun, 23 Jun 2024 23:08:01 +0600 Subject: [PATCH] pkp/pkp-lib#9434 added exmaple of injecting a closure based route --- ApiExamplePlugin.php | 28 ++++++++++++++++++++++++++- README.md | 23 ++++++++++++++++++++++ api/v1/tests/PluginTestController.php | 10 ++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/ApiExamplePlugin.php b/ApiExamplePlugin.php index 70a4d34..b835082 100644 --- a/ApiExamplePlugin.php +++ b/ApiExamplePlugin.php @@ -20,10 +20,14 @@ namespace APP\plugins\generic\apiExample; use APP\plugins\generic\apiExample\api\v1\users\PKPOverriddenUserController; +use Illuminate\Http\Request as IlluminateRequest; +use Illuminate\Http\Response; +use Illuminate\Http\JsonResponse; use PKP\core\PKPBaseController; use PKP\handler\APIHandler; use PKP\plugins\GenericPlugin; use PKP\plugins\Hook; +use PKP\security\Role; class ApiExamplePlugin extends GenericPlugin { @@ -61,7 +65,29 @@ public function register($category, $path, $mainContextId = null) public function addRoute(): void { Hook::add('APIHandler::endpoints::users', function(string $hookName, PKPBaseController &$apiController, APIHandler $apiHandler): bool { - + + // This allow to add a route on fly without defining a api controller + // Through this allow quick add/modify routes, it's better to use + // controller based appraoch which is more structured and understandable + $apiHandler->addRoute( + 'GET', + 'testing/routes/add/onfly', + function (IlluminateRequest $request): JsonResponse { + return response()->json([ + 'message' => 'A new route added successfully on fly', + ], Response::HTTP_OK); + }, + 'test.onfly', + [ + Role::ROLE_ID_SITE_ADMIN, + Role::ROLE_ID_MANAGER, + Role::ROLE_ID_SUB_EDITOR, + ] + ); + + // This allow to update the api controller directly with an overrided controller + // that extends a core controller where one or more routes can be added or + // multiple existing routes can be modified $apiController = new PKPOverriddenUserController(); return false; diff --git a/README.md b/README.md index 698ceec..2c95c10 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,29 @@ Hook::add('APIHandler::endpoints::users', function(string $hookName, PKPBaseCont }); ``` +Another way to add or override api routes to an existing entity is to use the closure based appraoch to add a route directly in the route collection. + +```php +Hook::add('APIHandler::endpoints::users', function(string $hookName, PKPBaseController &$apiController, APIHandler $apiHandler): bool { + + $apiHandler->addRoute( + 'GET/POST/PUT/PATCH/DELETE', // HTTP Request METHOD + 'some/route/path/to/add', // The route uri + function (IlluminateRequest $request): JsonResponse { // The closure/callback of route action handler when the route url got hit + return response()->json([ + 'message' => 'A new route added successfully', + ], Response::HTTP_OK); + }, + 'name.of.the.route', // Name of the route + [Role::ROLE_ID_..., Role::ROLE_ID_..., ...] // The route accessable role from `Role::ROLE_ID_*` + ); + + return false; +}); +``` + +> NOTE : Above approach to inject route dynamically through the `APIHandler::addRoute` should be used for simple route implementation that handle very simple and limited action logic. For broad and complex route action, better to use the controller based approach. + Also see the same implementation in [Plugin Code](https://github.com/touhidurabir/apiExample/blob/main/api/v1/users/PKPOverriddenUserController.php) . diff --git a/api/v1/tests/PluginTestController.php b/api/v1/tests/PluginTestController.php index ab8ae33..dac8392 100644 --- a/api/v1/tests/PluginTestController.php +++ b/api/v1/tests/PluginTestController.php @@ -76,6 +76,16 @@ public function authorize(PKPRequest $request, array &$args, array $roleAssignme /** * A simple plugin level api endpoint can be access as * http://BASE_URL/index.php/CONTEXT_PATH/plugins/generic/apiExample/api/v1/tests + * + * To generate the API URL of a plugin : + * + * Application::get()->getRequest()->getRouter()->url( + * request: Application::get()->getRequest(), + * newContext: Application::get()->getRequest()->getContext()?->getPath(), + * endpoint: 'tests', + * pluginOptions: ['generic', 'apiExample'] + * ) + * */ public function get(Request $request): JsonResponse {