feat: Add licensing module backend
- LicensingSettings.php with key format, activation limits, expiry settings - LicenseManager.php with key generation, activation/deactivation, validation - LicensingModule.php with WooCommerce product meta integration - LicensesController.php with admin, customer, and public API endpoints - Database tables: woonoow_licenses, woonoow_license_activations - has_settings enabled in ModuleRegistry
This commit is contained in:
291
includes/Api/LicensesController.php
Normal file
291
includes/Api/LicensesController.php
Normal file
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
/**
|
||||
* Licenses API Controller
|
||||
*
|
||||
* REST API endpoints for license management.
|
||||
*
|
||||
* @package WooNooW\Api
|
||||
*/
|
||||
|
||||
namespace WooNooW\Api;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
use WP_REST_Request;
|
||||
use WP_REST_Response;
|
||||
use WP_Error;
|
||||
use WooNooW\Core\ModuleRegistry;
|
||||
use WooNooW\Modules\Licensing\LicenseManager;
|
||||
|
||||
class LicensesController {
|
||||
|
||||
/**
|
||||
* Register REST routes
|
||||
*/
|
||||
public static function register_routes() {
|
||||
// Check if module is enabled
|
||||
if (!ModuleRegistry::is_enabled('licensing')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Admin routes
|
||||
register_rest_route('woonoow/v1', '/licenses', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_licenses'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_woocommerce');
|
||||
},
|
||||
]);
|
||||
|
||||
register_rest_route('woonoow/v1', '/licenses/(?P<id>\d+)', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_license'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_woocommerce');
|
||||
},
|
||||
]);
|
||||
|
||||
register_rest_route('woonoow/v1', '/licenses/(?P<id>\d+)', [
|
||||
'methods' => 'DELETE',
|
||||
'callback' => [__CLASS__, 'revoke_license'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_woocommerce');
|
||||
},
|
||||
]);
|
||||
|
||||
register_rest_route('woonoow/v1', '/licenses/(?P<id>\d+)/activations', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_activations'],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_woocommerce');
|
||||
},
|
||||
]);
|
||||
|
||||
// Customer routes
|
||||
register_rest_route('woonoow/v1', '/account/licenses', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_customer_licenses'],
|
||||
'permission_callback' => function() {
|
||||
return is_user_logged_in();
|
||||
},
|
||||
]);
|
||||
|
||||
register_rest_route('woonoow/v1', '/account/licenses/(?P<id>\d+)/deactivate', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'customer_deactivate'],
|
||||
'permission_callback' => function() {
|
||||
return is_user_logged_in();
|
||||
},
|
||||
]);
|
||||
|
||||
// Public API routes (for software validation)
|
||||
register_rest_route('woonoow/v1', '/licenses/validate', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'validate_license'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
|
||||
register_rest_route('woonoow/v1', '/licenses/activate', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'activate_license'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
|
||||
register_rest_route('woonoow/v1', '/licenses/deactivate', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [__CLASS__, 'deactivate_license'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all licenses (admin)
|
||||
*/
|
||||
public static function get_licenses(WP_REST_Request $request) {
|
||||
$args = [
|
||||
'search' => $request->get_param('search'),
|
||||
'status' => $request->get_param('status'),
|
||||
'product_id' => $request->get_param('product_id'),
|
||||
'user_id' => $request->get_param('user_id'),
|
||||
'limit' => $request->get_param('per_page') ?: 50,
|
||||
'offset' => (($request->get_param('page') ?: 1) - 1) * ($request->get_param('per_page') ?: 50),
|
||||
];
|
||||
|
||||
$result = LicenseManager::get_all_licenses($args);
|
||||
|
||||
// Enrich with product and user info
|
||||
foreach ($result['licenses'] as &$license) {
|
||||
$license = self::enrich_license($license);
|
||||
}
|
||||
|
||||
return new WP_REST_Response([
|
||||
'licenses' => $result['licenses'],
|
||||
'total' => $result['total'],
|
||||
'page' => $request->get_param('page') ?: 1,
|
||||
'per_page' => $args['limit'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single license (admin)
|
||||
*/
|
||||
public static function get_license(WP_REST_Request $request) {
|
||||
$license = LicenseManager::get_license($request->get_param('id'));
|
||||
|
||||
if (!$license) {
|
||||
return new WP_Error('not_found', __('License not found', 'woonoow'), ['status' => 404]);
|
||||
}
|
||||
|
||||
$license = self::enrich_license($license);
|
||||
$license['activations'] = LicenseManager::get_activations($license['id']);
|
||||
|
||||
return new WP_REST_Response($license);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke license (admin)
|
||||
*/
|
||||
public static function revoke_license(WP_REST_Request $request) {
|
||||
$result = LicenseManager::revoke($request->get_param('id'));
|
||||
|
||||
if (!$result) {
|
||||
return new WP_Error('revoke_failed', __('Failed to revoke license', 'woonoow'), ['status' => 500]);
|
||||
}
|
||||
|
||||
return new WP_REST_Response(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get activations for license (admin)
|
||||
*/
|
||||
public static function get_activations(WP_REST_Request $request) {
|
||||
$activations = LicenseManager::get_activations($request->get_param('id'));
|
||||
return new WP_REST_Response($activations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customer's licenses
|
||||
*/
|
||||
public static function get_customer_licenses(WP_REST_Request $request) {
|
||||
$user_id = get_current_user_id();
|
||||
$licenses = LicenseManager::get_user_licenses($user_id);
|
||||
|
||||
// Enrich each license
|
||||
foreach ($licenses as &$license) {
|
||||
$license = self::enrich_license($license);
|
||||
$license['activations'] = LicenseManager::get_activations($license['id']);
|
||||
}
|
||||
|
||||
return new WP_REST_Response($licenses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customer deactivate their own activation
|
||||
*/
|
||||
public static function customer_deactivate(WP_REST_Request $request) {
|
||||
$user_id = get_current_user_id();
|
||||
$license = LicenseManager::get_license($request->get_param('id'));
|
||||
|
||||
if (!$license || $license['user_id'] != $user_id) {
|
||||
return new WP_Error('not_found', __('License not found', 'woonoow'), ['status' => 404]);
|
||||
}
|
||||
|
||||
$data = $request->get_json_params();
|
||||
$result = LicenseManager::deactivate(
|
||||
$license['license_key'],
|
||||
$data['activation_id'] ?? null,
|
||||
$data['machine_id'] ?? null
|
||||
);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return new WP_REST_Response($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate license (public API)
|
||||
*/
|
||||
public static function validate_license(WP_REST_Request $request) {
|
||||
$data = $request->get_json_params();
|
||||
|
||||
if (empty($data['license_key'])) {
|
||||
return new WP_Error('missing_key', __('License key is required', 'woonoow'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$result = LicenseManager::validate($data['license_key']);
|
||||
return new WP_REST_Response($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate license (public API)
|
||||
*/
|
||||
public static function activate_license(WP_REST_Request $request) {
|
||||
$data = $request->get_json_params();
|
||||
|
||||
if (empty($data['license_key'])) {
|
||||
return new WP_Error('missing_key', __('License key is required', 'woonoow'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$activation_data = [
|
||||
'domain' => $data['domain'] ?? null,
|
||||
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
|
||||
'machine_id' => $data['machine_id'] ?? null,
|
||||
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
|
||||
];
|
||||
|
||||
$result = LicenseManager::activate($data['license_key'], $activation_data);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return new WP_REST_Response($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate license (public API)
|
||||
*/
|
||||
public static function deactivate_license(WP_REST_Request $request) {
|
||||
$data = $request->get_json_params();
|
||||
|
||||
if (empty($data['license_key'])) {
|
||||
return new WP_Error('missing_key', __('License key is required', 'woonoow'), ['status' => 400]);
|
||||
}
|
||||
|
||||
$result = LicenseManager::deactivate(
|
||||
$data['license_key'],
|
||||
$data['activation_id'] ?? null,
|
||||
$data['machine_id'] ?? null
|
||||
);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return new WP_REST_Response($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich license with product and user info
|
||||
*/
|
||||
private static function enrich_license($license) {
|
||||
// Add product info
|
||||
$product = wc_get_product($license['product_id']);
|
||||
$license['product_name'] = $product ? $product->get_name() : __('Unknown Product', 'woonoow');
|
||||
|
||||
// Add user info
|
||||
$user = get_userdata($license['user_id']);
|
||||
$license['user_email'] = $user ? $user->user_email : '';
|
||||
$license['user_name'] = $user ? $user->display_name : __('Unknown User', 'woonoow');
|
||||
|
||||
// Add computed fields
|
||||
$license['is_expired'] = $license['expires_at'] && strtotime($license['expires_at']) < time();
|
||||
$license['activations_remaining'] = $license['activation_limit'] > 0
|
||||
? max(0, $license['activation_limit'] - $license['activation_count'])
|
||||
: -1;
|
||||
|
||||
return $license;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ use WooNooW\Api\ModulesController;
|
||||
use WooNooW\Api\ModuleSettingsController;
|
||||
use WooNooW\Api\CampaignsController;
|
||||
use WooNooW\Api\DocsController;
|
||||
use WooNooW\Api\LicensesController;
|
||||
use WooNooW\Frontend\ShopController;
|
||||
use WooNooW\Frontend\CartController as FrontendCartController;
|
||||
use WooNooW\Frontend\AccountController;
|
||||
@@ -158,6 +159,9 @@ class Routes {
|
||||
// Campaigns controller
|
||||
CampaignsController::register_routes();
|
||||
|
||||
// Licenses controller (licensing module)
|
||||
LicensesController::register_routes();
|
||||
|
||||
// Modules controller
|
||||
$modules_controller = new ModulesController();
|
||||
$modules_controller->register_routes();
|
||||
|
||||
Reference in New Issue
Block a user