diff --git a/assets/js/user-badges.js b/assets/js/user-badges.js index 24df0b37..04ed5e8d 100644 --- a/assets/js/user-badges.js +++ b/assets/js/user-badges.js @@ -347,8 +347,8 @@ var data = r.json && r.json.data; var isSelf = data && data.is_self; if (isSelf && data.wear) { - refreshed = (window.aksrtData && window.aksrtData.ajaxUrl) - ? window.aksrtData.ajaxUrl + '?action=aksrt_single_badge_info_modal&name=' + encodeURIComponent(data.wear) + '&user_id=' + (uid || 0) + refreshed = uid > 0 && data.wear + ? window.AksrtRequest.url('/users/' + uid + '/badges/' + encodeURIComponent(data.wear) + '/modal') : null; } } catch (_) {} diff --git a/src/User/Badges.php b/src/User/Badges.php index 308dd91a..ff69551e 100644 --- a/src/User/Badges.php +++ b/src/User/Badges.php @@ -30,11 +30,6 @@ class Badges { public function init(): void { add_action('rest_api_init', [$this, 'register_routes']); add_action('aksrt_badge_granted', [$this, 'on_badge_granted_notify'], 10, 3); - // HTML modal for modal runtime (zibll user_medal_info_modal). - add_action('wp_ajax_aksrt_user_badge_info_modal', [$this, 'ajax_info_modal']); - add_action('wp_ajax_nopriv_aksrt_user_badge_info_modal', [$this, 'ajax_info_modal']); - add_action('wp_ajax_aksrt_single_badge_info_modal', [$this, 'ajax_single_info_modal']); - add_action('wp_ajax_nopriv_aksrt_single_badge_info_modal', [$this, 'ajax_single_info_modal']); } /** @@ -71,39 +66,32 @@ class Badges { } /** - * AJAX: full badge list modal HTML. + * REST response for the badge list modal. */ - public function ajax_info_modal(): void { - $user_id = max(0, (int) ($_REQUEST['id'] ?? $_REQUEST['user_id'] ?? 0)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - if ($user_id <= 0) { - $user_id = get_current_user_id(); - } + public function rest_modal_list(\WP_REST_Request $request) { + $user_id = absint($request->get_param('id')); if ($user_id <= 0 || !get_userdata($user_id)) { - wp_send_json_error(['message' => __('用户不存在', 'aksrt')], 404); + return new \WP_Error('aksrt_badge_user_missing', __('用户不存在', 'aksrt'), ['status' => 404]); } - $html = self::render_info_modal_html($user_id); - wp_send_json_success(['html' => $html]); + return new \WP_REST_Response(['html' => self::render_info_modal_html($user_id)], 200); } /** - * AJAX: single badge detail modal. + * REST response for a single badge modal. */ - public function ajax_single_info_modal(): void { - $slug = sanitize_key((string) ($_REQUEST['name'] ?? $_REQUEST['slug'] ?? '')); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $user_id = max(0, (int) ($_REQUEST['user_id'] ?? $_REQUEST['id'] ?? 0)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + public function rest_modal_single(\WP_REST_Request $request) { + $slug = sanitize_key((string) $request->get_param('slug')); + $user_id = absint($request->get_param('id')); if ($slug === '') { - wp_send_json_error(['message' => __('徽章不存在', 'aksrt')], 404); + return new \WP_Error('aksrt_badge_missing', __('徽章不存在', 'aksrt'), ['status' => 404]); } - $html = self::render_single_modal_html($slug, $user_id); - wp_send_json_success(['html' => $html]); + return new \WP_REST_Response(['html' => self::render_single_modal_html($slug, $user_id)], 200); } /** - * Badge list modal HTML (zibll zib_get_user_medal_info_modal parity). + * Badge list modal HTML. * - * Head (avatar + owner + worn medal) + category-grouped medal card grid. - * Each card deep-links into the single badge modal via the modal runtime - * contract (data-aksrt-modal="remote" + data-aksrt-modal-url). + * Head (avatar + owner + worn medal) and category-grouped medal card grid. */ public static function render_info_modal_html(int $user_id): string { $user = get_userdata($user_id); @@ -162,7 +150,7 @@ class Badges { // Footer: quick jump to my own badges while browsing someone else (zibll). if (!$is_self && $current > 0) { - $my_url = add_query_arg(['action' => 'aksrt_user_badge_info_modal', 'id' => $current], admin_url('admin-ajax.php')); + $my_url = rest_url('aksrt/v1/users/' . $current . '/badges/modal'); $html .= '