244 lines
10 KiB
PHP
244 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* @package AKSRT
|
|
*/
|
|
|
|
namespace AKSRT\Admin\Native;
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
class UsersMenus {
|
|
|
|
use UsersMenusVerify;
|
|
use UsersMenusVip;
|
|
use UsersMenusInviteCode;
|
|
use UsersMenusBan;
|
|
use UsersMenusTicketsCenter;
|
|
use UsersMenusMessages;
|
|
|
|
public const CAPABILITY = 'manage_options';
|
|
|
|
private static $instance = null;
|
|
|
|
public static function get_instance(): self {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
public function init(): void {
|
|
if (!is_admin()) {
|
|
return;
|
|
}
|
|
|
|
NativeUi::boot();
|
|
add_action('admin_menu', [$this, 'register_menus']);
|
|
add_action('admin_notices', [$this, 'pending_notices']);
|
|
add_action('admin_post_aksrt_users_send_message', [$this, 'handle_send_message']);
|
|
add_action('admin_post_aksrt_users_bulk_messages', [$this, 'handle_bulk_messages']);
|
|
add_action('admin_post_aksrt_users_review_verify', [$this, 'handle_review_verify']);
|
|
add_action('admin_post_aksrt_users_delete_verify', [$this, 'handle_delete_verify']);
|
|
add_action('admin_post_aksrt_users_update_report', [$this, 'handle_update_report']);
|
|
add_action('admin_post_aksrt_users_process_appeal', [$this, 'handle_process_appeal']);
|
|
add_action('admin_post_aksrt_users_mutate_vip', [$this, 'handle_mutate_vip']);
|
|
add_action('admin_post_aksrt_ticket_update', [$this, 'handle_ticket_update']);
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_ticket_assets']);
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_message_assets']);
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_invite_assets']);
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_verify_assets']);
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_ban_assets']);
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_vip_assets']);
|
|
}
|
|
|
|
public function register_menus(): void {
|
|
add_submenu_page(
|
|
'users.php',
|
|
__('邀请码管理', 'aksrt'),
|
|
__('邀请码管理', 'aksrt'),
|
|
'edit_users',
|
|
'aksrt_invite_codes',
|
|
[$this, 'render_invite_codes_page']
|
|
);
|
|
|
|
if (!current_user_can(self::CAPABILITY)) {
|
|
return;
|
|
}
|
|
|
|
add_submenu_page(
|
|
'users.php',
|
|
__('消息管理', 'aksrt'),
|
|
__('消息管理', 'aksrt'),
|
|
self::CAPABILITY,
|
|
'aksrt_messages',
|
|
[$this, 'render_messages_page']
|
|
);
|
|
add_submenu_page(
|
|
'users.php',
|
|
__('用户会员', 'aksrt'),
|
|
__('用户会员', 'aksrt'),
|
|
self::CAPABILITY,
|
|
'aksrt_user_vip',
|
|
[$this, 'render_vip_page']
|
|
);
|
|
add_submenu_page(
|
|
'users.php',
|
|
__('身份认证', 'aksrt'),
|
|
__('身份认证', 'aksrt'),
|
|
self::CAPABILITY,
|
|
'aksrt_user_auth',
|
|
[$this, 'render_verify_page']
|
|
);
|
|
add_submenu_page(
|
|
'users.php',
|
|
__('处理举报及禁封申诉', 'aksrt'),
|
|
__('举报&禁封申诉', 'aksrt'),
|
|
self::CAPABILITY,
|
|
'aksrt_user_ban',
|
|
[$this, 'render_ban_page']
|
|
);
|
|
add_submenu_page(
|
|
'users.php',
|
|
__('工单管理', 'aksrt'),
|
|
__('工单管理', 'aksrt'),
|
|
self::CAPABILITY,
|
|
'aksrt_tickets',
|
|
[$this, 'render_tickets_page']
|
|
);
|
|
}
|
|
|
|
public function pending_notices(): void {
|
|
if (!current_user_can(self::CAPABILITY)) {
|
|
return;
|
|
}
|
|
$page = isset($_GET['page']) ? sanitize_key((string) wp_unslash($_GET['page'])) : '';
|
|
|
|
if ($page !== 'aksrt_user_auth') {
|
|
$pending_verify = $this->count_verify_status('pending');
|
|
if ($pending_verify > 0) {
|
|
$url = admin_url('users.php?page=aksrt_user_auth&status=pending');
|
|
echo '<div class="notice notice-info is-dismissible"><h3>' . esc_html__('用户身份认证申请待处理', 'aksrt') . '</h3>';
|
|
echo '<p>' . esc_html(sprintf(
|
|
/* translators: %d count */
|
|
__('您有 %d 个用户身份认证申请待处理', 'aksrt'),
|
|
$pending_verify
|
|
)) . '</p>';
|
|
echo '<p><a class="button button-primary" href="' . esc_url($url) . '">' . esc_html__('立即处理', 'aksrt') . '</a></p></div>';
|
|
}
|
|
}
|
|
|
|
if ($page !== 'aksrt_user_ban' && class_exists('\AKSRT\Messages\ReportCenter')) {
|
|
$pending_reports = (int) \AKSRT\Messages\ReportCenter::get_instance()->get_pending_count();
|
|
if ($pending_reports > 0) {
|
|
$url = admin_url('users.php?page=aksrt_user_ban&status=pending');
|
|
echo '<div class="notice notice-info is-dismissible"><h3>' . esc_html__('举报待处理', 'aksrt') . '</h3>';
|
|
echo '<p>' . esc_html(sprintf(
|
|
/* translators: %d count */
|
|
__('您有 %d 条举报待处理', 'aksrt'),
|
|
$pending_reports
|
|
)) . '</p>';
|
|
echo '<p><a class="button button-primary" href="' . esc_url($url) . '">' . esc_html__('立即处理', 'aksrt') . '</a></p></div>';
|
|
}
|
|
}
|
|
|
|
if ($page !== 'aksrt_user_ban' && class_exists('\AKSRT\User\BanAppeal')) {
|
|
$pending_appeals = count(get_users([
|
|
'meta_key' => \AKSRT\User\BanAppeal::META_STATUS,
|
|
'meta_value' => 'pending',
|
|
'number' => 50,
|
|
'fields' => 'ID',
|
|
]));
|
|
if ($pending_appeals > 0) {
|
|
$url = admin_url('users.php?page=aksrt_user_ban&type=appeal&status=pending');
|
|
echo '<div class="notice notice-warning is-dismissible"><h3>' . esc_html__('禁封申诉待处理', 'aksrt') . '</h3>';
|
|
echo '<p>' . esc_html(sprintf(__('您有 %d 条禁封申诉待处理', 'aksrt'), $pending_appeals)) . '</p>';
|
|
echo '<p><a class="button button-primary" href="' . esc_url($url) . '">' . esc_html__('立即处理', 'aksrt') . '</a></p></div>';
|
|
}
|
|
}
|
|
|
|
if ($page !== 'aksrt_tickets' && class_exists('\AKSRT\Ticket\TicketSettings') && \AKSRT\Ticket\TicketSettings::enabled()) {
|
|
$pending_tickets = $this->count_pending_tickets();
|
|
if ($pending_tickets > 0) {
|
|
$url = admin_url('users.php?page=aksrt_tickets&status=' . \AKSRT\Ticket\TicketStatusService::KEY_PENDING);
|
|
echo '<div class="notice notice-info is-dismissible"><h3>' . esc_html__('工单待接单', 'aksrt') . '</h3>';
|
|
echo '<p>' . esc_html(sprintf(
|
|
/* translators: %d count */
|
|
__('您有 %d 个工单待接单', 'aksrt'),
|
|
$pending_tickets
|
|
)) . '</p>';
|
|
echo '<p><a class="button button-primary" href="' . esc_url($url) . '">' . esc_html__('立即处理', 'aksrt') . '</a></p></div>';
|
|
}
|
|
}
|
|
}
|
|
|
|
private function ensure_cap(): void {
|
|
if (!current_user_can(self::CAPABILITY)) {
|
|
wp_die(esc_html__('您没有权限访问此页面。', 'aksrt'));
|
|
}
|
|
}
|
|
|
|
private function flash(): void {
|
|
if (empty($_GET['aksrt_users_msg'])) {
|
|
return;
|
|
}
|
|
$code = sanitize_key((string) wp_unslash($_GET['aksrt_users_msg']));
|
|
$map = [
|
|
'verify_updated' => __('认证状态已更新。', 'aksrt'),
|
|
'verify_deleted' => __('认证记录已删除。', 'aksrt'),
|
|
'verify_failed' => __('认证审核失败。', 'aksrt'),
|
|
'report_updated' => __('举报状态已更新。', 'aksrt'),
|
|
'report_failed' => __('举报更新失败。', 'aksrt'),
|
|
'appeal_approved' => __('申诉已通过,限制已解除。', 'aksrt'),
|
|
'appeal_rejected' => __('申诉已驳回。', 'aksrt'),
|
|
'appeal_failed' => __('申诉处理失败。', 'aksrt'),
|
|
'vip_updated' => __('会员状态已更新。', 'aksrt'),
|
|
'vip_partial' => __('部分用户的会员状态已更新。', 'aksrt'),
|
|
'vip_failed' => __('会员操作失败。', 'aksrt'),
|
|
];
|
|
if (!isset($map[$code])) {
|
|
return;
|
|
}
|
|
$class = str_contains($code, 'failed') ? 'notice-error' : 'notice-success';
|
|
$message = $map[$code];
|
|
if ($code === 'verify_failed' && isset($_GET['aksrt_verify_error'])) {
|
|
$message = sanitize_text_field((string) wp_unslash($_GET['aksrt_verify_error']));
|
|
}
|
|
if (in_array($code, ['report_failed', 'appeal_failed'], true) && isset($_GET['aksrt_ban_error'])) {
|
|
$message = sanitize_text_field((string) wp_unslash($_GET['aksrt_ban_error']));
|
|
}
|
|
if ($code === 'vip_failed' && isset($_GET['aksrt_vip_error'])) {
|
|
$message = sanitize_text_field((string) wp_unslash($_GET['aksrt_vip_error']));
|
|
}
|
|
if (in_array($code, ['vip_updated', 'vip_partial'], true)) {
|
|
$message .= ' ' . sprintf(
|
|
__('成功:%1$d;失败:%2$d;跳过:%3$d。', 'aksrt'),
|
|
absint($_GET['aksrt_vip_ok'] ?? 0),
|
|
absint($_GET['aksrt_vip_failed_count'] ?? 0),
|
|
absint($_GET['aksrt_vip_skipped'] ?? 0)
|
|
);
|
|
}
|
|
echo '<div class="notice ' . esc_attr($class) . ' is-dismissible"><p>' . esc_html($message) . '</p></div>';
|
|
}
|
|
|
|
private function redirect(string $page, string $msg, array $extra = []): void {
|
|
wp_safe_redirect(add_query_arg(array_merge(['page' => $page, 'aksrt_users_msg' => $msg], $extra), admin_url('users.php')));
|
|
exit;
|
|
}
|
|
|
|
private function pagination(int $pages, int $page_num): void {
|
|
if ($pages <= 1) {
|
|
return;
|
|
}
|
|
echo '<div class="tablenav"><div class="tablenav-pages">';
|
|
echo paginate_links([
|
|
'base' => add_query_arg('paged', '%#%'),
|
|
'format' => '',
|
|
'prev_text' => '«',
|
|
'next_text' => '»',
|
|
'total' => $pages,
|
|
'current' => $page_num,
|
|
]);
|
|
echo '</div></div>';
|
|
}
|
|
}
|