Skip to content

Commit

Permalink
enhance: Seperate dokan rest controller for role-wise API implementat…
Browse files Browse the repository at this point in the history
…ion. (#2484)

* 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.
  • Loading branch information
MdAsifHossainNadim authored Dec 19, 2024
1 parent 3e3ddd0 commit 198afb2
Show file tree
Hide file tree
Showing 5 changed files with 403 additions and 50 deletions.
271 changes: 271 additions & 0 deletions docs/api/api.md
Original file line number Diff line number Diff line change
@@ -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 );
}
}
```
53 changes: 3 additions & 50 deletions includes/Abstracts/DokanRESTAdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

namespace WeDevs\Dokan\Abstracts;

use WP_REST_Controller;

/**
* Admin Dashboard
*
* @since 2.8.0
*
* @package dokan
*/
abstract class DokanRESTAdminController extends WP_REST_Controller {
abstract class DokanRESTAdminController extends DokanRESTBaseController {

/**
* Endpoint namespace.
Expand All @@ -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;
}
}
Loading

0 comments on commit 198afb2

Please sign in to comment.