Files
wordpress-theme-aksrt/inc/classes/forum/board-service-traits/trait-aksrt-forum-board-service-part-3.php
T
kate522 cf6ad0e972 feat(forum,admin): plate follow-pay MVP, sales column, order type tabs
Wire paid plate follow (admin meta + points/balance purchase + AJAX),
re-check plate gate on topics, post list sales column, and order type
subtabs; update gap matrix and admin IA map.
2026-07-15 11:00:36 +08:00

175 lines
6.0 KiB
PHP

<?php
defined('ABSPATH') || exit;
trait AKSRT_Forum_Board_Service_Part_3 {
/**
* Check if a user is a plate_cat moderator (分区版主).
*/
public function is_cat_moderator(int $user_id, int $cat_id): bool {
if ($user_id <= 0) {
return false;
}
if ($this->forum->is_forum_admin($user_id)) {
return true;
}
$moderator_ids = get_term_meta($cat_id, '_aksrt_cat_moderator', true);
if (!is_array($moderator_ids)) {
return false;
}
return in_array($user_id, array_map('intval', $moderator_ids), true);
}
/**
* Get plates sorted by a specified dimension (§7.2 多维排序).
*/
public function get_sorted_plates(string $orderby = 'menu_order', string $order = 'ASC', int $limit = 50): array {
$allowed = [
'name' => 'title',
'date' => 'date',
'modified' => 'modified',
'menu_order' => 'menu_order',
'last_post' => '_aksrt_last_post',
'last_reply' => '_aksrt_last_reply',
'posts_count' => '_aksrt_posts_count',
'reply_count' => '_aksrt_reply_count',
'today_reply_count' => '_aksrt_today_reply_count',
'views' => '_aksrt_views',
'follow_count' => '_aksrt_follow_count',
'rand' => 'rand',
];
$query_args = [
'post_type' => 'aksrt_forum_plate',
'post_status' => 'publish',
'posts_per_page' => $limit,
'order' => strtoupper($order) === 'ASC' ? 'ASC' : 'DESC',
];
if (isset($allowed[$orderby])) {
$meta_key = $allowed[$orderby];
if (str_starts_with($meta_key, '_aksrt_')) {
$query_args['orderby'] = 'meta_value_num';
$query_args['meta_key'] = $meta_key;
} else {
$query_args['orderby'] = $meta_key;
}
} else {
$query_args['orderby'] = 'menu_order';
}
$posts = get_posts($query_args);
$plates = [];
foreach ($posts as $post) {
$plates[] = $this->build_plate_payload($post);
}
return $plates;
}
public function maybe_migrate_boards(): void {
if (get_option('aksrt_forum_boards_migrated')) {
return;
}
$old_boards = get_option('aksrt_forum_boards', []);
if (!is_array($old_boards) || empty($old_boards)) {
update_option('aksrt_forum_boards_migrated', time());
return;
}
foreach ($old_boards as $board) {
$name = sanitize_text_field((string) ($board['name'] ?? ''));
if ($name === '') {
continue;
}
$existing = get_terms([
'taxonomy' => 'aksrt_forum_board',
'name' => $name,
'hide_empty' => false,
'fields' => 'ids',
]);
if (!is_wp_error($existing) && !empty($existing)) {
$term_id = (int) $existing[0];
} else {
$result = wp_insert_term($name, 'aksrt_forum_board', [
'description' => sanitize_textarea_field((string) ($board['description'] ?? '')),
]);
if (is_wp_error($result)) {
continue;
}
$term_id = (int) $result['term_id'];
}
$icon = sanitize_text_field((string) ($board['icon'] ?? ''));
if ($icon !== '') {
update_term_meta($term_id, '_aksrt_icon', $icon);
}
update_term_meta($term_id, '_aksrt_sort_order', (int) ($board['sort_order'] ?? $term_id));
if (!empty($board['moderators']) && is_array($board['moderators'])) {
update_term_meta($term_id, '_aksrt_moderators', array_map('intval', $board['moderators']));
}
}
update_option('aksrt_forum_boards_migrated', time());
}
public function ajax_follow_plate(): void {
check_ajax_referer('aksrt_forum_action', '_nonce');
$user_id = get_current_user_id();
if ($user_id <= 0) {
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
}
$plate_id = (int) ($_POST['plate_id'] ?? 0);
if ($plate_id <= 0) {
wp_send_json_error(['message' => __('版块不存在', 'aksrt')]);
}
$result = $this->toggle_follow_plate($user_id, $plate_id);
if (!empty($result['require_pay'])) {
wp_send_json_error([
'code' => 'require_pay',
'message' => (string) ($result['message'] ?? __('需要付费关注', 'aksrt')),
'require_pay' => true,
'pay' => $result['pay'] ?? [],
'followed' => false,
'follow_count' => (int) ($result['follow_count'] ?? 0),
]);
}
if (isset($result['success']) && $result['success'] === false) {
wp_send_json_error([
'message' => (string) ($result['message'] ?? __('操作失败', 'aksrt')),
]);
}
wp_send_json_success($result);
}
public function ajax_purchase_plate_follow(): void {
check_ajax_referer('aksrt_forum_action', '_nonce');
$user_id = get_current_user_id();
if ($user_id <= 0) {
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
}
$plate_id = (int) ($_POST['plate_id'] ?? 0);
if ($plate_id <= 0) {
wp_send_json_error(['message' => __('版块不存在', 'aksrt')]);
}
$result = $this->purchase_plate_follow($user_id, $plate_id);
if (empty($result['success'])) {
wp_send_json_error([
'message' => (string) ($result['message'] ?? __('支付失败', 'aksrt')),
]);
}
wp_send_json_success($result);
}
}