feat: Affiliate program enrichment (Link Builder, Curated Collections, Smart Links)
This commit is contained in:
@@ -48,6 +48,33 @@ class AffiliateCustomerController
|
||||
'callback' => [$this, 'update_payment_details'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// Affiliate Collections
|
||||
register_rest_route($this->namespace, '/account/affiliate/collections', [
|
||||
[
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [$this, 'get_collections'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
],
|
||||
[
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => [$this, 'create_collection'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/account/affiliate/collections/(?P<id>\d+)', [
|
||||
[
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => [$this, 'update_collection'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
],
|
||||
[
|
||||
'methods' => WP_REST_Server::DELETABLE,
|
||||
'callback' => [$this, 'delete_collection'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function check_permission()
|
||||
@@ -89,6 +116,12 @@ class AffiliateCustomerController
|
||||
$affiliate['commission_rate'] = $effective_rate;
|
||||
$affiliate['total_earnings'] = $earnings->total_earnings ?: 0;
|
||||
$affiliate['pending_earnings'] = $earnings->pending_earnings ?: 0;
|
||||
|
||||
if (class_exists('\WooNooW\Modules\Affiliate\AffiliateSettings')) {
|
||||
$affiliate['collections_enabled'] = \WooNooW\Modules\Affiliate\AffiliateSettings::get_setting('woonoow_affiliate_enable_curated_collections', true);
|
||||
} else {
|
||||
$affiliate['collections_enabled'] = true;
|
||||
}
|
||||
|
||||
return rest_ensure_response($affiliate);
|
||||
}
|
||||
@@ -318,4 +351,125 @@ class AffiliateCustomerController
|
||||
|
||||
return $sanitized;
|
||||
}
|
||||
|
||||
// --- Collections ---
|
||||
|
||||
public function get_collections(WP_REST_Request $request)
|
||||
{
|
||||
if (class_exists('\WooNooW\Modules\Affiliate\AffiliateSettings') && !\WooNooW\Modules\Affiliate\AffiliateSettings::get_setting('woonoow_affiliate_enable_curated_collections', true)) {
|
||||
return new \WP_Error('rest_forbidden', 'Curated collections are disabled.', ['status' => 403]);
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$user_id = get_current_user_id();
|
||||
$affiliate_table = $wpdb->prefix . 'woonoow_affiliates';
|
||||
$collections_table = $wpdb->prefix . 'woonoow_affiliate_collections';
|
||||
|
||||
$affiliate = $wpdb->get_row($wpdb->prepare("SELECT id, referral_code FROM $affiliate_table WHERE user_id = %d", $user_id));
|
||||
if (!$affiliate) {
|
||||
return rest_ensure_response([]);
|
||||
}
|
||||
|
||||
$collections = $wpdb->get_results($wpdb->prepare("SELECT * FROM $collections_table WHERE affiliate_id = %d ORDER BY created_at DESC", $affiliate->id), ARRAY_A);
|
||||
|
||||
foreach ($collections as &$collection) {
|
||||
$collection['product_ids'] = $collection['product_ids'] ? json_decode($collection['product_ids'], true) : [];
|
||||
$collection['link'] = site_url("/collection/{$collection['slug']}");
|
||||
}
|
||||
|
||||
return rest_ensure_response($collections);
|
||||
}
|
||||
|
||||
public function create_collection(WP_REST_Request $request)
|
||||
{
|
||||
global $wpdb;
|
||||
$user_id = get_current_user_id();
|
||||
$affiliate_table = $wpdb->prefix . 'woonoow_affiliates';
|
||||
$collections_table = $wpdb->prefix . 'woonoow_affiliate_collections';
|
||||
|
||||
$affiliate = $wpdb->get_row($wpdb->prepare("SELECT id FROM $affiliate_table WHERE user_id = %d", $user_id));
|
||||
if (!$affiliate) {
|
||||
return new \WP_Error('not_found', 'Affiliate profile not found', ['status' => 404]);
|
||||
}
|
||||
|
||||
$title = sanitize_text_field($request->get_param('title'));
|
||||
$description = sanitize_textarea_field($request->get_param('description'));
|
||||
$product_ids = $request->get_param('product_ids');
|
||||
if (!is_array($product_ids)) $product_ids = [];
|
||||
|
||||
$product_ids = array_map('intval', $product_ids);
|
||||
if (count($product_ids) > 20) {
|
||||
return new \WP_Error('too_many_products', 'A collection can have a maximum of 20 products.', ['status' => 400]);
|
||||
}
|
||||
|
||||
$slug = sanitize_title($title);
|
||||
// Check unique slug for this affiliate
|
||||
$existing = $wpdb->get_var($wpdb->prepare("SELECT id FROM $collections_table WHERE affiliate_id = %d AND slug = %s", $affiliate->id, $slug));
|
||||
if ($existing) {
|
||||
$slug .= '-' . wp_generate_password(4, false);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'affiliate_id' => $affiliate->id,
|
||||
'title' => $title,
|
||||
'slug' => $slug,
|
||||
'description' => $description,
|
||||
'product_ids' => json_encode($product_ids)
|
||||
];
|
||||
|
||||
$wpdb->insert($collections_table, $data);
|
||||
$data['id'] = $wpdb->insert_id;
|
||||
$data['product_ids'] = $product_ids;
|
||||
|
||||
return rest_ensure_response($data);
|
||||
}
|
||||
|
||||
public function update_collection(WP_REST_Request $request)
|
||||
{
|
||||
global $wpdb;
|
||||
$user_id = get_current_user_id();
|
||||
$id = (int) $request->get_param('id');
|
||||
$affiliate_table = $wpdb->prefix . 'woonoow_affiliates';
|
||||
$collections_table = $wpdb->prefix . 'woonoow_affiliate_collections';
|
||||
|
||||
$affiliate = $wpdb->get_row($wpdb->prepare("SELECT id FROM $affiliate_table WHERE user_id = %d", $user_id));
|
||||
if (!$affiliate) return new \WP_Error('unauthorized', 'Unauthorized', ['status' => 401]);
|
||||
|
||||
$collection = $wpdb->get_row($wpdb->prepare("SELECT id FROM $collections_table WHERE id = %d AND affiliate_id = %d", $id, $affiliate->id));
|
||||
if (!$collection) return new \WP_Error('not_found', 'Collection not found', ['status' => 404]);
|
||||
|
||||
$title = sanitize_text_field($request->get_param('title'));
|
||||
$description = sanitize_textarea_field($request->get_param('description'));
|
||||
$product_ids = $request->get_param('product_ids');
|
||||
if (!is_array($product_ids)) $product_ids = [];
|
||||
|
||||
$product_ids = array_map('intval', $product_ids);
|
||||
if (count($product_ids) > 20) {
|
||||
return new \WP_Error('too_many_products', 'A collection can have a maximum of 20 products.', ['status' => 400]);
|
||||
}
|
||||
|
||||
$wpdb->update($collections_table, [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'product_ids' => json_encode($product_ids)
|
||||
], ['id' => $id]);
|
||||
|
||||
return rest_ensure_response(['success' => true]);
|
||||
}
|
||||
|
||||
public function delete_collection(WP_REST_Request $request)
|
||||
{
|
||||
global $wpdb;
|
||||
$user_id = get_current_user_id();
|
||||
$id = (int) $request->get_param('id');
|
||||
$affiliate_table = $wpdb->prefix . 'woonoow_affiliates';
|
||||
$collections_table = $wpdb->prefix . 'woonoow_affiliate_collections';
|
||||
|
||||
$affiliate = $wpdb->get_row($wpdb->prepare("SELECT id FROM $affiliate_table WHERE user_id = %d", $user_id));
|
||||
if (!$affiliate) return new \WP_Error('unauthorized', 'Unauthorized', ['status' => 401]);
|
||||
|
||||
$wpdb->delete($collections_table, ['id' => $id, 'affiliate_id' => $affiliate->id]);
|
||||
|
||||
return rest_ensure_response(['success' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user