From dbaf57cdc65f65acbd3b05033f09444a4a547742 Mon Sep 17 00:00:00 2001 From: "Md. Asif Hossain Nadim" <90011088+MdAsifHossainNadim@users.noreply.github.com> Date: Tue, 24 Dec 2024 11:58:25 +0600 Subject: [PATCH] enhance: Seperate dokan rest controller for role-wise API implementation. (#2484) (#2492) * enhance: Split dokan rest controller class for role-wise API implementation. * fix: Update rest base for admin, vendor, customer controllers. * fix: api documentation for admin controller usecase. * fix: update base api class name `DokanBaseRESTController` to `DokanRESTBaseController`, remove redunded properties, update api docs. --- docs/api/api.md | 271 ++++++++++++++++++ .../Abstracts/DokanRESTAdminController.php | 53 +--- .../Abstracts/DokanRESTBaseController.php | 67 +++++ .../Abstracts/DokanRESTCustomerController.php | 31 ++ .../Abstracts/DokanRESTVendorController.php | 31 ++ 5 files changed, 403 insertions(+), 50 deletions(-) create mode 100644 docs/api/api.md create mode 100644 includes/Abstracts/DokanRESTBaseController.php create mode 100644 includes/Abstracts/DokanRESTCustomerController.php create mode 100644 includes/Abstracts/DokanRESTVendorController.php diff --git a/docs/api/api.md b/docs/api/api.md new file mode 100644 index 0000000000..5a16bf980e --- /dev/null +++ b/docs/api/api.md @@ -0,0 +1,271 @@ +# Dokan REST Controllers Documentation + +- [Introduction](#introduction) +- [Base REST Controller](#base-rest-controller) +- [1. Role-Specific Controllers.](#1-role-specifix-controllers) + - [Admin REST Controller.](#admin-rest-controller) + - [Vendor REST Controller.](#vendor-rest-controller) + - [Customer REST Controller.](#customer-rest-controller) + +## Introduction +The Dokan REST Controllers provide a structured approach to handle REST API endpoints with role-based permissions. The hierarchy consists of a base controller (`DokanRESTBaseController`) and role-specific controllers (`DokanRESTAdminController`, `DokanRESTVendorController`, `DokanRESTCustomerController`). + +## Base REST Controller +The `DokanRESTBaseController` extends WordPress's `WP_REST_Controller` and provides common functionality for all Dokan REST endpoints. + +### Base Controller Implementation +```php +abstract class DokanRESTBaseController extends WP_REST_Controller { + protected $namespace = 'dokan/v1'; + + public function format_collection_response( $response, $request, $total_items ) { + // Handles pagination and response formatting + } +} +``` + +## Role-Specific Controllers + +### Admin REST Controller Implementation + +```php +abstract class DokanRESTAdminController extends DokanRESTBaseController { + protected $namespace = 'dokan/v1/admin'; + + public function check_permission() { + return current_user_can( 'manage_woocommerce' ); + } +} +``` + +### How to extend the Admin REST Controller + +```php +class ExampleAdminController extends DokanRESTAdminController { + protected $namespace = 'dokan/v1'; + protected $rest_base = 'example-admin'; + + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => [ $this, 'check_permission' ], + 'args' => $this->get_collection_params(), + ] + ] + ); + } + + public function get_items( $request ) { + $items = []; // Your implementation + $total = count( $items ); + + $response = rest_ensure_response( $items ); + return $this->format_collection_response( $response, $request, $total ); + } +} +``` + +### Override Admin REST Controller permission + +```php +class ExampleAdminController extends DokanRESTAdminController { + protected $namespace = 'dokan/v1'; + protected $rest_base = 'example-admin'; + + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => [ $this, 'check_permission' ], + 'args' => $this->get_collection_params(), + ] + ] + ); + } + + public function check_permission() { + // Custom permission check for multiple roles + return current_user_can( 'dokandar' ) || current_user_can( 'manage_woocommerce' ); + } + + public function get_items( $request ) { + $items = []; // Your implementation + $total = count( $items ); + + $response = rest_ensure_response( $items ); + return $this->format_collection_response( $response, $request, $total ); + } +} +``` + +### Vendor REST Controller Implementation + +```php +abstract class DokanRESTVendorController extends DokanRESTBaseController { + protected $rest_base = 'vendor'; + + public function check_permission() { + return current_user_can( 'dokandar' ); + } +} +``` + +### How to extend the Vendor REST Controller + +```php +class ExampleVendorController extends DokanRESTVendorController { + // protected $namespace = 'dokan/v1'; (namespace will be inherited from the parent class) + protected $rest_base = 'example-vendor'; + + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => [ $this, 'check_permission' ], + 'args' => $this->get_collection_params(), + ] + ] + ); + } + + public function get_items( $request ) { + $items = []; // Your implementation + $total = count( $items ); + + $response = rest_ensure_response( $items ); + return $this->format_collection_response( $response, $request, $total ); + } +} +``` + +### Override Vendor REST Controller permission + +```php +class ExampleVendorController extends DokanRESTVendorController { + // protected $namespace = 'dokan/v1'; (namespace will be inherited from the parent class) + protected $rest_base = 'example-vendor'; + + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => [ $this, 'check_permission' ], + 'args' => $this->get_collection_params(), + ] + ] + ); + } + + public function check_permission() { + // Custom permission check. + return current_user_can( 'dokandar' ) || is_user_logged_in(); + } + + public function get_items( $request ) { + $items = []; // Your implementation + $total = count( $items ); + + $response = rest_ensure_response( $items ); + return $this->format_collection_response( $response, $request, $total ); + } +} +``` + +### Customer REST Controller Implementation + +```php +abstract class DokanRESTCustomerController extends DokanRESTBaseController { + // protected $namespace = 'dokan/v1'; (namespace will be inherited from the parent class) + protected $rest_base = 'customer'; + + public function check_permission() { + return is_user_logged_in(); + } +} +``` + +### How to extend the Customer REST Controller + +```php +class ExampleCustomerController extends DokanRESTCustomerController { + // protected $namespace = 'dokan/v1'; (namespace will be inherited from the parent class) + protected $rest_base = 'example-customer'; + + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => [ $this, 'check_permission' ], + 'args' => $this->get_collection_params(), + ] + ] + ); + } + + public function get_items( $request ) { + $items = []; // Your implementation + $total = count( $items ); + + $response = rest_ensure_response( $items ); + return $this->format_collection_response( $response, $request, $total ); + } +} +``` + +### Override Customer REST Controller permission + +```php +class ExampleCustomerController extends DokanRESTCustomerController { + // protected $namespace = 'dokan/v1'; (namespace will be inherited from the parent class) + protected $rest_base = 'example-customer'; + + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + [ + [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => [ $this, 'check_permission' ], + 'args' => $this->get_collection_params(), + ] + ] + ); + } + + public function check_permission() { + // Custom permission check. + return is_user_logged_in() || dokan_is_seller_enabled( get_current_user_id() );; + } + + public function get_items( $request ) { + $items = []; // Your implementation + $total = count( $items ); + + $response = rest_ensure_response( $items ); + return $this->format_collection_response( $response, $request, $total ); + } +} +``` diff --git a/includes/Abstracts/DokanRESTAdminController.php b/includes/Abstracts/DokanRESTAdminController.php index 44c6b5090e..16f0307161 100644 --- a/includes/Abstracts/DokanRESTAdminController.php +++ b/includes/Abstracts/DokanRESTAdminController.php @@ -2,8 +2,6 @@ namespace WeDevs\Dokan\Abstracts; -use WP_REST_Controller; - /** * Admin Dashboard * @@ -11,7 +9,7 @@ * * @package dokan */ -abstract class DokanRESTAdminController extends WP_REST_Controller { +abstract class DokanRESTAdminController extends DokanRESTBaseController { /** * Endpoint namespace. @@ -21,58 +19,13 @@ abstract class DokanRESTAdminController extends WP_REST_Controller { protected $namespace = 'dokan/v1/admin'; /** - * Perform permission checking + * Check if user has admin permission. * * @since 2.8.0 * - * @return void + * @return bool */ public function check_permission() { return current_user_can( 'manage_woocommerce' ); } - - /** - * Format item's collection for response - * - * @param object $response - * @param object $request - * @param array $items - * @param int $total_items - * - * @since 2.9.8 - * - * @return object - */ - public function format_collection_response( $response, $request, $total_items ) { - if ( $total_items === 0 ) { - return $response; - } - - // pagation values for headers - $per_page = (int) ( ! empty( $request['per_page'] ) ? $request['per_page'] : 20 ); - $page = (int) ( ! empty( $request['page'] ) ? $request['page'] : 1 ); - - $response->header( 'X-WP-Total', (int) $total_items ); - - $max_pages = ceil( $total_items / $per_page ); - - $response->header( 'X-WP-TotalPages', (int) $max_pages ); - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->base ) ) ); - - if ( $page > 1 ) { - $prev_page = $page - 1; - if ( $prev_page > $max_pages ) { - $prev_page = $max_pages; - } - $prev_link = add_query_arg( 'page', $prev_page, $base ); - $response->link_header( 'prev', $prev_link ); - } - if ( $max_pages > $page ) { - $next_page = $page + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - $response->link_header( 'next', $next_link ); - } - - return $response; - } } diff --git a/includes/Abstracts/DokanRESTBaseController.php b/includes/Abstracts/DokanRESTBaseController.php new file mode 100644 index 0000000000..16485fe422 --- /dev/null +++ b/includes/Abstracts/DokanRESTBaseController.php @@ -0,0 +1,67 @@ +header( 'X-WP-Total', (int) $total_items ); + + $max_pages = ceil( $total_items / $per_page ); + + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->base ) ) ); + + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } +} diff --git a/includes/Abstracts/DokanRESTCustomerController.php b/includes/Abstracts/DokanRESTCustomerController.php new file mode 100644 index 0000000000..a2c13cc3ea --- /dev/null +++ b/includes/Abstracts/DokanRESTCustomerController.php @@ -0,0 +1,31 @@ +