ensure_cap(); $filters = $this->message_filters(); $paged = max(1, absint($_GET['paged'] ?? 1)); echo '
'; return; } $query = $this->message_query_filters($filters); $result = NotificationAdminQuery::paginate($query, $paged); $this->render_message_overview(); $this->render_message_compose(); $this->render_message_views($filters, NotificationAdminQuery::status_counts($query)); $this->render_message_filter_form($filters); $this->render_message_table($result['items'], $filters, $result['page'], $query['user_id'] < 0); AdminListPagination::render( self::MESSAGE_PAGE_SLUG, $result['total'], $result['page'], NotificationAdminQuery::PER_PAGE, $this->message_filter_args($filters), 'users.php' ); echo ''; } /* ------------------------------------------------------------------ * 写操作 * ----------------------------------------------------------------*/ public function handle_send_message(): void { $this->ensure_cap(); check_admin_referer('aksrt_users_send_message'); $mode = sanitize_key((string) wp_unslash($_POST['recipient_mode'] ?? 'users')); $title = trim(sanitize_text_field((string) wp_unslash($_POST['title'] ?? ''))); $content = trim(sanitize_textarea_field((string) wp_unslash($_POST['content'] ?? ''))); $target_url = esc_url_raw(trim((string) wp_unslash($_POST['target_url'] ?? ''))); if ($content === '') { $this->message_fail(__('请填写消息内容。', 'aksrt')); } if (mb_strlen($content) > AdminBroadcast::CONTENT_MAX) { $this->message_fail(sprintf(__('消息内容不能超过 %d 字。', 'aksrt'), AdminBroadcast::CONTENT_MAX)); } $title = mb_substr($title !== '' ? $title : $content, 0, AdminBroadcast::TITLE_MAX); $unknown = 0; if ($mode === 'role') { $ids = AdminBroadcast::resolve_role(sanitize_key((string) wp_unslash($_POST['role'] ?? ''))); } else { $resolved = AdminBroadcast::resolve_users(sanitize_textarea_field((string) wp_unslash($_POST['users'] ?? ''))); $ids = is_wp_error($resolved) ? $resolved : $resolved['ids']; $unknown = is_wp_error($resolved) ? 0 : count($resolved['unknown']); } if (is_wp_error($ids)) { $this->message_fail($ids->get_error_message()); } if ($ids === []) { $this->message_fail(__('没有匹配到任何有效收件人。', 'aksrt')); } $sent = AdminBroadcast::send($ids, $title, $content, $target_url); $this->message_redirect([ 'aksrt_msg' => $sent['sent'] > 0 ? 'sent' : 'send_failed', 'aksrt_msg_n' => $sent['sent'], 'aksrt_msg_f' => $sent['failed'], 'aksrt_msg_u' => $unknown, ]); } public function handle_bulk_messages(): void { $this->ensure_cap(); check_admin_referer('aksrt_users_bulk_messages'); $op = sanitize_key((string) wp_unslash($_POST['bulk_action'] ?? '')); $ids = isset($_POST['ids']) && is_array($_POST['ids']) ? array_map('absint', wp_unslash($_POST['ids'])) : []; $back = $this->message_filter_args($this->message_filters($_POST)); $paged = absint($_POST['paged'] ?? 0); if ($paged > 1) { $back['paged'] = $paged; } if (!in_array($op, ['delete', 'mark_read'], true) || array_filter($ids) === []) { $this->message_redirect(array_merge($back, ['aksrt_msg' => 'bulk_none'])); } $count = $op === 'delete' ? NotificationAdminQuery::delete($ids) : NotificationAdminQuery::mark_read($ids); $this->message_redirect(array_merge($back, [ 'aksrt_msg' => $op === 'delete' ? 'deleted' : 'marked', 'aksrt_msg_n' => $count, ])); } /* ------------------------------------------------------------------ * 区块渲染 * ----------------------------------------------------------------*/ private function render_message_notices(): void { $code = sanitize_key((string) wp_unslash($_GET['aksrt_msg'] ?? '')); if ($code === '') { return; } $n = absint($_GET['aksrt_msg_n'] ?? 0); $error = false; switch ($code) { case 'sent': $text = sprintf(__('已发送 %d 条消息。', 'aksrt'), $n); $failed = absint($_GET['aksrt_msg_f'] ?? 0); $unknown = absint($_GET['aksrt_msg_u'] ?? 0); if ($failed > 0) { $text .= ' ' . sprintf(__('投递失败 %d 条。', 'aksrt'), $failed); } if ($unknown > 0) { $text .= ' ' . sprintf(__('%d 个收件人未找到,已跳过。', 'aksrt'), $unknown); } break; case 'send_failed': $error = true; $text = isset($_GET['aksrt_msg_error']) ? sanitize_text_field((string) wp_unslash($_GET['aksrt_msg_error'])) : __('消息发送失败。', 'aksrt'); break; case 'deleted': $text = sprintf(__('已删除 %d 条消息。', 'aksrt'), $n); break; case 'marked': $text = sprintf(__('已将 %d 条消息标记为已读。', 'aksrt'), $n); break; case 'bulk_none': $error = true; $text = __('请先勾选消息并选择操作。', 'aksrt'); break; default: return; } printf( '%s