refactor(badges): use modal REST routes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 00:16:39 +08:00
co-authored by Claude Fable 5
parent 34150f3358
commit 25ce1d8f43
2 changed files with 51 additions and 41 deletions
+2 -2
View File
@@ -347,8 +347,8 @@
var data = r.json && r.json.data; var data = r.json && r.json.data;
var isSelf = data && data.is_self; var isSelf = data && data.is_self;
if (isSelf && data.wear) { if (isSelf && data.wear) {
refreshed = (window.aksrtData && window.aksrtData.ajaxUrl) refreshed = uid > 0 && data.wear
? window.aksrtData.ajaxUrl + '?action=aksrt_single_badge_info_modal&name=' + encodeURIComponent(data.wear) + '&user_id=' + (uid || 0) ? window.AksrtRequest.url('/users/' + uid + '/badges/' + encodeURIComponent(data.wear) + '/modal')
: null; : null;
} }
} catch (_) {} } catch (_) {}
+49 -39
View File
@@ -30,11 +30,6 @@ class Badges {
public function init(): void { public function init(): void {
add_action('rest_api_init', [$this, 'register_routes']); add_action('rest_api_init', [$this, 'register_routes']);
add_action('aksrt_badge_granted', [$this, 'on_badge_granted_notify'], 10, 3); 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 { public function rest_modal_list(\WP_REST_Request $request) {
$user_id = max(0, (int) ($_REQUEST['id'] ?? $_REQUEST['user_id'] ?? 0)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $user_id = absint($request->get_param('id'));
if ($user_id <= 0) {
$user_id = get_current_user_id();
}
if ($user_id <= 0 || !get_userdata($user_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); return new \WP_REST_Response(['html' => self::render_info_modal_html($user_id)], 200);
wp_send_json_success(['html' => $html]);
} }
/** /**
* AJAX: single badge detail modal. * REST response for a single badge modal.
*/ */
public function ajax_single_info_modal(): void { public function rest_modal_single(\WP_REST_Request $request) {
$slug = sanitize_key((string) ($_REQUEST['name'] ?? $_REQUEST['slug'] ?? '')); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $slug = sanitize_key((string) $request->get_param('slug'));
$user_id = max(0, (int) ($_REQUEST['user_id'] ?? $_REQUEST['id'] ?? 0)); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $user_id = absint($request->get_param('id'));
if ($slug === '') { 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); return new \WP_REST_Response(['html' => self::render_single_modal_html($slug, $user_id)], 200);
wp_send_json_success(['html' => $html]);
} }
/** /**
* 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. * Head (avatar + owner + worn medal) and 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).
*/ */
public static function render_info_modal_html(int $user_id): string { public static function render_info_modal_html(int $user_id): string {
$user = get_userdata($user_id); $user = get_userdata($user_id);
@@ -162,7 +150,7 @@ class Badges {
// Footer: quick jump to my own badges while browsing someone else (zibll). // Footer: quick jump to my own badges while browsing someone else (zibll).
if (!$is_self && $current > 0) { 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 .= '<div class="medal-modal__buts">'; $html .= '<div class="medal-modal__buts">';
$html .= '<a class="but c-blue" href="' . esc_url($my_url) . '" data-aksrt-modal="remote" data-aksrt-modal-url="' . esc_url($my_url) . '" data-aksrt-modal-class="full-sm" data-aksrt-modal-mobile-bottom="true"><i class="fas fa-medal" aria-hidden="true"></i> ' . esc_html__('查看我的徽章', 'aksrt') . '</a>'; $html .= '<a class="but c-blue" href="' . esc_url($my_url) . '" data-aksrt-modal="remote" data-aksrt-modal-url="' . esc_url($my_url) . '" data-aksrt-modal-class="full-sm" data-aksrt-modal-mobile-bottom="true"><i class="fas fa-medal" aria-hidden="true"></i> ' . esc_html__('查看我的徽章', 'aksrt') . '</a>';
$html .= '</div>'; $html .= '</div>';
@@ -199,10 +187,7 @@ class Badges {
} }
$card .= '</div>'; $card .= '</div>';
$url = add_query_arg( $url = rest_url('aksrt/v1/users/' . $user_id . '/badges/' . rawurlencode($slug) . '/modal');
['action' => 'aksrt_single_badge_info_modal', 'name' => $slug, 'user_id' => $user_id],
admin_url('admin-ajax.php')
);
return '<a class="medal-list" href="' . esc_url($url) . '" data-aksrt-modal="remote" data-aksrt-modal-url="' . esc_url($url) . '" data-aksrt-modal-class="modal-mini" data-aksrt-modal-mobile-bottom="true">' . $card . '</a>'; return '<a class="medal-list" href="' . esc_url($url) . '" data-aksrt-modal="remote" data-aksrt-modal-url="' . esc_url($url) . '" data-aksrt-modal-class="modal-mini" data-aksrt-modal-mobile-bottom="true">' . $card . '</a>';
} }
@@ -262,7 +247,7 @@ class Badges {
// Back to the full badge list modal. // Back to the full badge list modal.
if ($user_id > 0) { if ($user_id > 0) {
$back_url = add_query_arg(['action' => 'aksrt_user_badge_info_modal', 'id' => $user_id], admin_url('admin-ajax.php')); $back_url = rest_url('aksrt/v1/users/' . $user_id . '/badges/modal');
$html .= '<a class="medal-modal__back muted-2-color em09" href="' . esc_url($back_url) . '" data-aksrt-modal="remote" data-aksrt-modal-url="' . esc_url($back_url) . '" data-aksrt-modal-class="full-sm" data-aksrt-modal-mobile-bottom="true"><i class="fas fa-angle-left" aria-hidden="true"></i> ' . esc_html__('返回徽章列表', 'aksrt') . '</a>'; $html .= '<a class="medal-modal__back muted-2-color em09" href="' . esc_url($back_url) . '" data-aksrt-modal="remote" data-aksrt-modal-url="' . esc_url($back_url) . '" data-aksrt-modal-class="full-sm" data-aksrt-modal-mobile-bottom="true"><i class="fas fa-angle-left" aria-hidden="true"></i> ' . esc_html__('返回徽章列表', 'aksrt') . '</a>';
} }
@@ -271,7 +256,7 @@ class Badges {
} }
/** /**
* Remote-modal trigger for a user's badge list (zibll zib_get_user_medal_info_link). * Declarative modal runtime trigger for a user's badge list.
*/ */
public static function get_info_link(int $user_id, string $class = '', ?string $text = null): string { public static function get_info_link(int $user_id, string $class = '', ?string $text = null): string {
if ($user_id <= 0 || !self::enabled()) { if ($user_id <= 0 || !self::enabled()) {
@@ -283,13 +268,7 @@ class Badges {
if (!function_exists('aksrt_get_modal_link')) { if (!function_exists('aksrt_get_modal_link')) {
return ''; return '';
} }
$url = add_query_arg( $url = rest_url('aksrt/v1/users/' . $user_id . '/badges/modal');
[
'action' => 'aksrt_user_badge_info_modal',
'id' => $user_id,
],
admin_url('admin-ajax.php')
);
return aksrt_get_modal_link([ return aksrt_get_modal_link([
'tag' => 'a', 'tag' => 'a',
'class' => trim('user-medal-info ' . $class), 'class' => trim('user-medal-info ' . $class),
@@ -315,6 +294,37 @@ class Badges {
], ],
]); ]);
register_rest_route('aksrt/v1', '/users/(?P<id>\d+)/badges/modal', [
'methods' => 'GET',
'callback' => [$this, 'rest_modal_list'],
'permission_callback' => '__return_true',
'args' => [
'id' => [
'type' => 'integer',
'required' => true,
'sanitize_callback' => 'absint',
],
],
]);
register_rest_route('aksrt/v1', '/users/(?P<id>\d+)/badges/(?P<slug>[a-z0-9_-]+)/modal', [
'methods' => 'GET',
'callback' => [$this, 'rest_modal_single'],
'permission_callback' => '__return_true',
'args' => [
'id' => [
'type' => 'integer',
'required' => true,
'sanitize_callback' => 'absint',
],
'slug' => [
'type' => 'string',
'required' => true,
'sanitize_callback' => 'sanitize_key',
],
],
]);
register_rest_route('aksrt/v1', '/users/me/badges/wear', [ register_rest_route('aksrt/v1', '/users/me/badges/wear', [
'methods' => 'POST', 'methods' => 'POST',
'callback' => [$this, 'rest_wear'], 'callback' => [$this, 'rest_wear'],