dokan-backend-dev
Provides conventions for developing Dokan backend PHP code, including namespace structure and hook management.
Install
mkdir -p .claude/skills/dokan-backend-dev && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/12198" && unzip -o skill.zip -d .claude/skills/dokan-backend-dev && rm skill.zipInstalls to .claude/skills/dokan-backend-dev
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Add or modify Dokan backend PHP code following project conventions. Use when creating new classes, methods, hooks, REST controllers, or modifying existing backend code. Invoke before writing PHP unit tests.Key capabilities
- →Create new PHP classes or services following conventions
- →Add hooks, filters, or REST endpoints
- →Modify existing backend PHP code
- →Implement the Manager pattern for subsystems
- →Register services using League Container
How it works
The skill provides guidance on Dokan backend PHP development, covering namespace, class conventions, Manager pattern, dependency injection, and REST API controllers.
Inputs & outputs
When to use dokan-backend-dev
- →Create new PHP classes or services
- →Add new REST endpoints or hooks
- →Modify backend PHP code
- →Write PHP unit tests
About this skill
Dokan Backend Development
This skill provides guidance for developing Dokan Lite backend PHP code according to project standards.
When to Use This Skill
Invoke this skill before:
- Writing new PHP unit tests
- Creating new PHP classes or services
- Modifying existing backend PHP code
- Adding hooks, filters, or REST endpoints
Namespace & File Structure
- Root namespace:
WeDevs\Dokan\ - PSR-4 autoloading:
WeDevs\Dokan\maps toincludes/ - File path follows namespace:
WeDevs\Dokan\Order\Manager→includes/Order/Manager.php - Third-party (Mozart):
WeDevs\Dokan\ThirdParty\Packages\→lib/packages/
Class Conventions
Method & Property Naming
- Methods:
snake_case(WordPress convention) — e.g.,register_routes(),get_stores() - Properties: typed (PHP 7.4+) — e.g.,
protected bool $should_adjust_refund = true; - Constants:
UPPER_SNAKE_CASE
Manager Pattern
Most subsystems use a Manager class as the primary facade:
namespace WeDevs\Dokan\Order;
class Manager {
public function all( $args = [] ) { ... }
public function get( $id ) { ... }
public function create( $args ) { ... }
}
Access via: dokan()->order->all()
Hookable Interface
Classes that register WordPress hooks should implement Hookable:
namespace WeDevs\Dokan\Product;
use WeDevs\Dokan\Contracts\Hookable;
class Hooks implements Hookable {
public function register_hooks(): void {
add_action( 'save_post_product', [ $this, 'handle_product_save' ], 10, 2 );
add_filter( 'dokan_product_listing_args', [ $this, 'filter_listing_args' ] );
}
}
Classes implementing Hookable are auto-registered in CommonServiceProvider — their hooks load automatically.
Dependency Injection
Uses League Container v4 (namespaced under WeDevs\Dokan\ThirdParty\Packages\League\Container).
Registering Services
Add to the appropriate ServiceProvider in includes/DependencyManagement/Providers/:
// In ServiceProvider.php (main) for core services:
protected $services = [
'my_service' => \WeDevs\Dokan\MyDomain\Manager::class,
];
// In CommonServiceProvider.php for Hookable classes:
protected $services = [
\WeDevs\Dokan\MyDomain\Hooks::class,
];
Accessing Services
// Via magic getter (most common)
dokan()->order->get( $order_id );
dokan()->vendor->get( $vendor_id );
// Via container directly
dokan()->get_container()->get( 'order' );
Base Service Provider Helper
Use share_with_implements_tags() to auto-tag services by their interfaces:
$this->share_with_implements_tags( MyService::class );
REST API Controllers
Controller Hierarchy
WP_REST_Controller (WordPress core)
└── DokanBaseController (dokan/v1)
├── DokanBaseAdminController (dokan/v1/admin) — admin-only endpoints
├── DokanBaseVendorController (dokan/v1) — vendor endpoints (uses VendorAuthorizable trait)
└── DokanBaseCustomerController (dokan/v1) — customer endpoints
Choose the appropriate base class:
DokanBaseAdminController— For admin-only endpoints (dokan/v1/admin/*). Has built-incheck_permission()checkingmanage_woocommercecapability.DokanBaseVendorController— For vendor endpoints. IncludesVendorAuthorizabletrait for store access checks.DokanBaseController— For general endpoints that don't fit the above.
Note: Some older controllers extend
WP_REST_Controllerdirectly (e.g.,StoreController,WithdrawController). New controllers should extend one of the Dokan base classes.
Full Controller Example
namespace WeDevs\Dokan\REST;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use WeDevs\Dokan\Traits\RESTResponseError;
class MyResourceController extends DokanBaseAdminController {
use RESTResponseError;
/**
* Route base.
*
* @var string
*/
protected $rest_base = 'my-resource';
/**
* Register routes.
*
* @return void
*/
public function register_routes() {
register_rest_route(
$this->namespace, '/' . $this->rest_base, [
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'get_items' ],
'args' => array_merge(
$this->get_collection_params(),
[
'status' => [
'description' => __( 'Filter by status.', 'dokan-lite' ),
'type' => 'string',
'enum' => [ 'active', 'inactive' ],
'default' => 'active',
],
]
),
'permission_callback' => [ $this, 'check_permission' ],
],
[
'methods' => WP_REST_Server::CREATABLE,
'callback' => [ $this, 'create_item' ],
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
'permission_callback' => [ $this, 'check_permission' ],
],
'schema' => [ $this, 'get_item_schema' ],
]
);
register_rest_route(
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', [
'args' => [
'id' => [
'description' => __( 'Unique identifier for the object.', 'dokan-lite' ),
'type' => 'integer',
],
],
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'get_item' ],
'permission_callback' => [ $this, 'check_permission' ],
],
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ $this, 'update_item' ],
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
'permission_callback' => [ $this, 'check_permission' ],
],
[
'methods' => WP_REST_Server::DELETABLE,
'callback' => [ $this, 'delete_item' ],
'permission_callback' => [ $this, 'check_permission' ],
],
]
);
// Batch endpoint
register_rest_route(
$this->namespace, '/' . $this->rest_base . '/batch', [
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ $this, 'batch_items' ],
'permission_callback' => [ $this, 'check_permission' ],
'args' => $this->get_public_batch_schema()['properties'],
],
'schema' => [ $this, 'get_public_batch_schema' ],
]
);
}
}
Prepare Item for Response
Every controller must implement prepare_item_for_response(). This method transforms the internal data model into the REST API response shape, adds HATEOAS links, and applies an extensibility filter:
/**
* Prepare a single item for response.
*
* @param MyModel $item Data object.
* @param WP_REST_Request $request Request object.
*
* @return WP_REST_Response
*/
public function prepare_item_for_response( $item, $request ) {
$data = [
'id' => absint( $item->get_id() ),
'title' => $item->get_title(),
'status' => $item->get_status(),
'amount' => floatval( $item->get_amount() ),
'created' => mysql_to_rfc3339( $item->get_date() ),
];
$data = apply_filters( 'dokan_rest_prepare_my_resource_data', $data, $item, $request );
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $item, $request ) );
return apply_filters( 'dokan_rest_prepare_my_resource_object', $response, $item, $request );
}
Prepare Links (HATEOAS)
Provide self and collection links for discoverability:
/**
* Prepare links for the request.
*
* @param MyModel $item Object data.
* @param WP_REST_Request $request Request object.
*
* @return array Links for the given item.
*/
protected function prepare_links( $item, $request ) {
return [
'self' => [
'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ),
],
'collection' => [
'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
],
];
}
Collection Response with Pagination
Use format_collection_response() (inherited from DokanBaseController) to add pagination headers:
public function get_items( $request ) {
$args = [
'number' => (int) $request['per_page'],
'offset' => (int) ( $request['page'] - 1 ) * $request['per_page'],
];
$items = $this->get_my_items( $args );
$total_items = $this->get_my_items_count( $args );
$data = [];
foreach ( $items as $item ) {
$item_data = $this->prepare_item_for_response( $item, $request );
$data[] = $this->prepare_response_for_collection( $item_data );
}
$response = rest_ensure_response( $data );
$response = $this->format_collection_response( $response, $request, $total_items );
return $response;
}
format_collection_response() sets these headers automatically:
X-WP-Total— Total item countX-WP-TotalPages— Total page count- `Link: <url>; rel="pr
Content truncated.
When not to use it
- →When writing new PHP unit tests (this skill is invoked before)
- →When using older controllers that extend WP_REST_Controller directly
- →When concatenating translated strings instead of using sprintf()
Limitations
- →Methods should use snake_case
- →Properties should be typed (PHP 7.4+)
- →New REST controllers should extend Dokan base classes
How it compares
This skill enforces specific coding standards and architectural patterns for Dokan backend development, ensuring consistency and maintainability across the project.
Compared to similar skills
dokan-backend-dev side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| dokan-backend-dev (this skill) | 0 | 5mo | Review | Intermediate |
| laravel-specialist | 12 | 3mo | No flags | Intermediate |
| developing-with-turbo-streams | 1 | 5mo | No flags | Intermediate |
| payment-integration | 1 | 6mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
laravel-specialist
Jeffallan
Use when building Laravel 10+ applications requiring Eloquent ORM, API resources, or queue systems. Invoke for Laravel models, Livewire components, Sanctum authentication, Horizon queues.
developing-with-turbo-streams
hotwired-laravel
Basics of developing with Turbo Streams in web applications. Activate when working on projects that utilize Turbo Streams for enhancing user experience through real-time updates, dynamic content changes, and partial page updates without full reloads.
payment-integration
mrgoonie
Integrate payments with SePay (VietQR), Polar, Stripe, Paddle (MoR subscriptions), Creem.io (licensing). Checkout, webhooks, subscriptions, QR codes, multi-provider orders.
developing-with-prism
prism-php
Guide for developing with Prism PHP package - a Laravel package for integrating LLMs. Activate or use when working with Prism features including text generation, structured output, embeddings, image generation, audio processing, streaming, tools/function calling, or any LLM provider integration (OpenAI, Anthropic, Gemini, Mistral, Groq, XAI, DeepSeek, OpenRouter, Ollama, VoyageAI, ElevenLabs). Activate for any Prism-related development tasks.
restapi-translations
mikopbx
Управление переводами REST API ключей (rest_*) для MikoPBX. Автоматически находит отсутствующие русские ключи в RestApi.php и синхронизирует их с исходным кодом. Использовать при проверке переводов API, после добавления новых endpoints или перед релизом.
moodle-external-api-development
davila7
Create custom external web service APIs for Moodle LMS. Use when implementing web services for course management, user tracking, quiz operations, or custom plugin functionality. Covers parameter validation, database operations, error handling, service registration, and Moodle coding standards.