refactor(classes): organize inc/classes into domain folders
Move ~94 root class shells and root *-traits into domain directories (core, auth, user, credits, content, payment/gateways, forum, shop, sms, ai, messages, extensions, widgets, settings, admin). Update bootstrap require paths, co-locate traits with owners, fix forum/user relative requires, drop duplicate shop controller requires, and wire home-modules load. Path-only; class names and init order unchanged.
This commit is contained in:
1 parent
2a8fe68048
commit
ce1c13b947
115 files changed
+171
-224
No files matched your search
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
* AKSRT Message — 站内通知系统
|
||||
*
|
||||
* 提供通知持久化(写入 aksrt_notification 表)、未读计数、标记已读。
|
||||
* 与 AKSRT_Private_Message 联动:私信发送时自动创建通知记录。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class AKSRT_Message {
|
||||
|
||||
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 {
|
||||
add_action('wp_ajax_aksrt_mark_message_read', [$this, 'ajax_mark_read']);
|
||||
add_action('wp_ajax_aksrt_get_unread_count', [$this, 'ajax_get_unread_count']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户未读消息数
|
||||
*/
|
||||
public function get_unread_count(int $user_id): int {
|
||||
if ($user_id <= 0) return 0;
|
||||
|
||||
// 优先从表中实时统计
|
||||
$table = $this->table();
|
||||
if ($table !== '') {
|
||||
global $wpdb;
|
||||
$count = (int) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$table} WHERE user_id = %d AND is_read = 0",
|
||||
$user_id
|
||||
));
|
||||
// 同步到 user_meta 以兼容旧读取方
|
||||
update_user_meta($user_id, 'aksrt_unread_message_count', $count);
|
||||
return $count;
|
||||
}
|
||||
|
||||
// 降级:从 user_meta 读取
|
||||
$count = (int) get_user_meta($user_id, 'aksrt_unread_message_count', true);
|
||||
return max(0, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记单条通知为已读
|
||||
*/
|
||||
public function mark_read(int $user_id, string $message_id): bool {
|
||||
if ($user_id <= 0 || empty($message_id)) return false;
|
||||
|
||||
$table = $this->table();
|
||||
if ($table !== '') {
|
||||
global $wpdb;
|
||||
$result = $wpdb->update(
|
||||
$table,
|
||||
['is_read' => 1, 'read_at' => current_time('mysql')],
|
||||
['id' => (int) $message_id, 'user_id' => $user_id, 'is_read' => 0],
|
||||
['%d', '%s'],
|
||||
['%d', '%d', '%d']
|
||||
);
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
// 降级:仅更新计数
|
||||
$current = $this->get_unread_count($user_id);
|
||||
if ($current > 0) {
|
||||
update_user_meta($user_id, 'aksrt_unread_message_count', max(0, $current - 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记用户所有通知为已读
|
||||
*/
|
||||
public function mark_all_read(int $user_id): bool {
|
||||
if ($user_id <= 0) return false;
|
||||
|
||||
$table = $this->table();
|
||||
if ($table !== '') {
|
||||
global $wpdb;
|
||||
$wpdb->update(
|
||||
$table,
|
||||
['is_read' => 1, 'read_at' => current_time('mysql')],
|
||||
['user_id' => $user_id, 'is_read' => 0],
|
||||
['%d', '%s'],
|
||||
['%d', '%d']
|
||||
);
|
||||
}
|
||||
|
||||
update_user_meta($user_id, 'aksrt_unread_message_count', 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送站内通知(持久化到 aksrt_notification 表)
|
||||
*
|
||||
* @param int $to_user_id 接收人 ID
|
||||
* @param string $type 通知类型 (comment_reply, download_ready, conversation, notice, ...)
|
||||
* @param string $content 通知内容摘要
|
||||
* @param array $data 附加数据 (title, target_url, ...)
|
||||
* @return bool
|
||||
*/
|
||||
public function send(int $to_user_id, string $type, string $content, array $data = []): bool {
|
||||
if ($to_user_id <= 0 || empty($content)) return false;
|
||||
|
||||
$table = $this->table();
|
||||
if ($table !== '') {
|
||||
global $wpdb;
|
||||
$wpdb->insert($table, [
|
||||
'user_id' => $to_user_id,
|
||||
'type' => sanitize_key($type),
|
||||
'title' => sanitize_text_field((string) ($data['title'] ?? $content)),
|
||||
'description' => sanitize_textarea_field($content),
|
||||
'target_url' => esc_url_raw((string) ($data['target_url'] ?? '')),
|
||||
'is_read' => 0,
|
||||
'created_at' => current_time('mysql'),
|
||||
], ['%d', '%s', '%s', '%s', '%s', '%d', '%s']);
|
||||
}
|
||||
|
||||
// 同步更新 user_meta 未读计数
|
||||
$current = (int) get_user_meta($to_user_id, 'aksrt_unread_message_count', true);
|
||||
update_user_meta($to_user_id, 'aksrt_unread_message_count', max(0, $current) + 1);
|
||||
|
||||
// 触发通知钩子
|
||||
do_action('aksrt_notification_sent', $to_user_id, $type, $data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户通知列表
|
||||
*/
|
||||
public function get_notifications(int $user_id, array $args = []): array {
|
||||
if ($user_id <= 0) return [];
|
||||
|
||||
$table = $this->table();
|
||||
if ($table !== '') {
|
||||
global $wpdb;
|
||||
|
||||
$where = ['user_id = %d'];
|
||||
$params = [$user_id];
|
||||
|
||||
$type = sanitize_key((string) ($args['type'] ?? ''));
|
||||
if ($type !== '' && $type !== 'all') {
|
||||
if ($type === 'unread') {
|
||||
$where[] = 'is_read = 0';
|
||||
} else {
|
||||
$where[] = 'type = %s';
|
||||
$params[] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
$limit = max(1, min(100, (int) ($args['limit'] ?? 20)));
|
||||
$offset = max(0, (int) ($args['offset'] ?? 0));
|
||||
|
||||
$where_sql = implode(' AND ', $where);
|
||||
$sql = "SELECT * FROM {$table} WHERE {$where_sql} ORDER BY created_at DESC LIMIT %d OFFSET %d";
|
||||
$params[] = $limit;
|
||||
$params[] = $offset;
|
||||
|
||||
return (array) $wpdb->get_results($wpdb->prepare($sql, $params), ARRAY_A);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通知收件箱完整视图(供 page-messages.php 使用)
|
||||
*/
|
||||
public function get_all_notifications(int $user_id): array {
|
||||
return $this->get_notifications($user_id, ['limit' => 200]);
|
||||
}
|
||||
|
||||
private function table(): string {
|
||||
if (class_exists('AKSRT_DB_Migrator')) {
|
||||
return AKSRT_DB_Migrator::table('notification');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX 标记已读
|
||||
*/
|
||||
public function ajax_mark_read(): void {
|
||||
check_ajax_referer('aksrt_message', '_nonce');
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
|
||||
$message_id = sanitize_text_field((string) ($_POST['message_id'] ?? ''));
|
||||
if ($this->mark_read($user_id, $message_id)) {
|
||||
wp_send_json_success(['unread' => $this->get_unread_count($user_id)]);
|
||||
}
|
||||
|
||||
wp_send_json_error(['message' => __('操作失败', 'aksrt')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX 获取未读数
|
||||
*/
|
||||
public function ajax_get_unread_count(): void {
|
||||
check_ajax_referer('aksrt_message', '_nonce');
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
|
||||
wp_send_json_success(['unread' => $this->get_unread_count($user_id)]);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user