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.
596 lines
22 KiB
PHP
596 lines
22 KiB
PHP
<?php
|
|
/**
|
|
* AKSRT User Notifications
|
|
*
|
|
* Notification CRUD, AJAX handlers, and event-driven notification creators.
|
|
*
|
|
* @package AKSRT
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
if (!function_exists('aksrt_get_user_notifications')) :
|
|
/**
|
|
* 获取用户提醒列表(即时提醒,不持久化)
|
|
*
|
|
* 当前通知源:
|
|
* - 邮箱待验证
|
|
* - 评论待审核
|
|
*
|
|
* @param int $user_id 用户 ID,默认当前用户
|
|
* @return array<int, array{type:string,title:string,desc:string,url:string,count:int}>
|
|
*/
|
|
function aksrt_get_user_notifications(int $user_id = 0): array {
|
|
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
|
if ($user_id <= 0) {
|
|
return [];
|
|
}
|
|
|
|
$items = [];
|
|
|
|
$email_verified = true;
|
|
if (class_exists('AKSRT_Auth_Service')) {
|
|
$email_verified = AKSRT_Auth_Service::user_is_email_verified($user_id);
|
|
}
|
|
|
|
if (!$email_verified && (!class_exists('AKSRT_Settings') || AKSRT_Settings::notification_enabled('verify_email'))) {
|
|
$items[] = [
|
|
'type' => 'verify_email',
|
|
'title' => __('邮箱待验证', 'aksrt'),
|
|
'desc' => __('请尽快完成邮箱验证,部分功能需要验证后才能使用。', 'aksrt'),
|
|
'url' => function_exists('aksrt_get_verify_email_url') ? aksrt_get_verify_email_url($user_id) : home_url('/'),
|
|
'count' => 1,
|
|
];
|
|
}
|
|
|
|
$pending_comments = (int) get_comments([
|
|
'user_id' => $user_id,
|
|
'count' => true,
|
|
'status' => 'hold',
|
|
]);
|
|
|
|
if ($pending_comments > 0 && (!class_exists('AKSRT_Settings') || AKSRT_Settings::notification_enabled('pending_comments'))) {
|
|
$items[] = [
|
|
'type' => 'pending_comments',
|
|
'title' => __('评论待审核', 'aksrt'),
|
|
'desc' => sprintf(__('你有 %d 条评论正在等待审核。', 'aksrt'), $pending_comments),
|
|
'url' => aksrt_get_user_center_url('comments'),
|
|
'count' => $pending_comments,
|
|
];
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_notification_type_label')) :
|
|
/** 通知类型中文标签 */
|
|
function aksrt_notification_type_label(string $type): string {
|
|
$map = [
|
|
'comment_reply' => __('评论回复', 'aksrt'),
|
|
'comment_approved' => __('评论审核', 'aksrt'),
|
|
'download_ready' => __('下载就绪', 'aksrt'),
|
|
'credits_added' => __('积分增加', 'aksrt'),
|
|
'credits_deducted' => __('积分扣减', 'aksrt'),
|
|
'verify_email' => __('邮箱验证', 'aksrt'),
|
|
'pending_comments' => __('待审核评论', 'aksrt'),
|
|
'notice' => __('通知', 'aksrt'),
|
|
];
|
|
return $map[$type] ?? $type;
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_get_user_notification_count')) :
|
|
/** 获取用户提醒总数 */
|
|
function aksrt_get_user_notification_count(int $user_id = 0): int {
|
|
$items = aksrt_get_user_notifications($user_id);
|
|
$count = 0;
|
|
foreach ($items as $item) {
|
|
$count += max(0, (int) ($item['count'] ?? 0));
|
|
}
|
|
return $count;
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_get_user_inbox_notifications')) :
|
|
/** 获取用户通知收件箱 */
|
|
function aksrt_get_user_inbox_notifications(int $user_id = 0): array {
|
|
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
|
if ($user_id <= 0) return [];
|
|
|
|
global $wpdb;
|
|
$table = class_exists('AKSRT_DB_Migrator') ? AKSRT_DB_Migrator::table('notification') : '';
|
|
if ($table === '') {
|
|
$items = get_user_meta($user_id, 'aksrt_notifications', true);
|
|
return is_array($items) ? array_values($items) : [];
|
|
}
|
|
|
|
static $migrated = [];
|
|
if (empty($migrated[$user_id])) {
|
|
$legacy = get_user_meta($user_id, 'aksrt_notifications', true);
|
|
if (is_array($legacy) && !empty($legacy)) {
|
|
foreach ($legacy as $item) {
|
|
aksrt_add_user_notification($user_id, [
|
|
'id' => $item['id'] ?? '',
|
|
'type' => $item['type'] ?? 'notice',
|
|
'title' => $item['title'] ?? '',
|
|
'desc' => $item['desc'] ?? '',
|
|
'url' => $item['url'] ?? '',
|
|
'read' => !empty($item['read']),
|
|
'created_at' => $item['created_at'] ?? current_time('mysql', true),
|
|
]);
|
|
}
|
|
delete_user_meta($user_id, 'aksrt_notifications');
|
|
}
|
|
$migrated[$user_id] = true;
|
|
}
|
|
|
|
$rows = $wpdb->get_results($wpdb->prepare(
|
|
"SELECT id, type, title, description, target_url, is_read, created_at, read_at
|
|
FROM {$table}
|
|
WHERE user_id = %d
|
|
ORDER BY created_at DESC, id DESC
|
|
LIMIT 50",
|
|
$user_id
|
|
), ARRAY_A);
|
|
|
|
if (!is_array($rows)) return [];
|
|
|
|
return array_map(static function ($row) {
|
|
return [
|
|
'id' => (string) ($row['id'] ?? ''),
|
|
'type' => (string) ($row['type'] ?? 'notice'),
|
|
'title' => (string) ($row['title'] ?? ''),
|
|
'desc' => (string) ($row['description'] ?? ''),
|
|
'url' => (string) ($row['target_url'] ?? ''),
|
|
'read' => !empty($row['is_read']) ? 1 : 0,
|
|
'created_at' => (string) ($row['created_at'] ?? ''),
|
|
'read_at' => (string) ($row['read_at'] ?? ''),
|
|
];
|
|
}, $rows);
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_schedule_notification_cleanup')) :
|
|
/** 注册通知清理定时任务 */
|
|
function aksrt_schedule_notification_cleanup(): void {
|
|
if (!wp_next_scheduled('aksrt_notification_cleanup')) {
|
|
$next = (new DateTimeImmutable('tomorrow 04:10', wp_timezone()))->getTimestamp();
|
|
wp_schedule_event($next, 'daily', 'aksrt_notification_cleanup');
|
|
}
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_cleanup_notifications')) :
|
|
/**
|
|
* 清理通知表:
|
|
* - 已读通知保留 30 天
|
|
* - 未读通知保留 180 天
|
|
* - 每个用户最多保留最近 200 条通知
|
|
*/
|
|
function aksrt_cleanup_notifications(): void {
|
|
global $wpdb;
|
|
|
|
$table = class_exists('AKSRT_DB_Migrator') ? AKSRT_DB_Migrator::table('notification') : '';
|
|
if ($table === '') {
|
|
return;
|
|
}
|
|
|
|
$settings = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_notification_settings() : [
|
|
'read_retention_days' => 30,
|
|
'unread_retention_days' => 180,
|
|
'max_per_user' => 200,
|
|
];
|
|
|
|
$read_retention_days = max(1, (int) ($settings['read_retention_days'] ?? 30));
|
|
$unread_retention_days = max(7, (int) ($settings['unread_retention_days'] ?? 180));
|
|
$max_per_user = max(20, (int) ($settings['max_per_user'] ?? 200));
|
|
|
|
$read_cutoff = (new DateTimeImmutable('-' . $read_retention_days . ' days', new DateTimeZone('UTC')))->format('Y-m-d H:i:s');
|
|
$unread_cutoff = (new DateTimeImmutable('-' . $unread_retention_days . ' days', new DateTimeZone('UTC')))->format('Y-m-d H:i:s');
|
|
|
|
$wpdb->query($wpdb->prepare(
|
|
"DELETE FROM {$table} WHERE is_read = 1 AND created_at < %s",
|
|
$read_cutoff
|
|
));
|
|
|
|
$wpdb->query($wpdb->prepare(
|
|
"DELETE FROM {$table} WHERE is_read = 0 AND created_at < %s",
|
|
$unread_cutoff
|
|
));
|
|
|
|
$user_ids = $wpdb->get_col("SELECT DISTINCT user_id FROM {$table}");
|
|
if (empty($user_ids)) {
|
|
return;
|
|
}
|
|
|
|
foreach ($user_ids as $user_id) {
|
|
$user_id = (int) $user_id;
|
|
if ($user_id <= 0) continue;
|
|
|
|
$ids = $wpdb->get_col($wpdb->prepare(
|
|
"SELECT id FROM {$table} WHERE user_id = %d ORDER BY created_at DESC, id DESC LIMIT %d, 1000",
|
|
$user_id,
|
|
$max_per_user
|
|
));
|
|
|
|
if (empty($ids)) {
|
|
continue;
|
|
}
|
|
|
|
$ids = array_map('absint', $ids);
|
|
$ids = array_filter($ids, static function ($id) { return $id > 0; });
|
|
if (empty($ids)) {
|
|
continue;
|
|
}
|
|
|
|
$wpdb->query("DELETE FROM {$table} WHERE id IN (" . implode(',', $ids) . ")");
|
|
}
|
|
}
|
|
endif;
|
|
|
|
add_action('wp', 'aksrt_schedule_notification_cleanup');
|
|
add_action('aksrt_notification_cleanup', 'aksrt_cleanup_notifications');
|
|
|
|
if (!function_exists('aksrt_write_user_inbox_notifications')) :
|
|
/** 写入用户通知收件箱 */
|
|
function aksrt_write_user_inbox_notifications(int $user_id, array $items): void {
|
|
if ($user_id <= 0) return;
|
|
global $wpdb;
|
|
$table = class_exists('AKSRT_DB_Migrator') ? AKSRT_DB_Migrator::table('notification') : '';
|
|
if ($table === '') {
|
|
update_user_meta($user_id, 'aksrt_notifications', array_values(array_slice($items, 0, 50)));
|
|
return;
|
|
}
|
|
|
|
$wpdb->delete($table, ['user_id' => $user_id], ['%d']);
|
|
$items = array_values(array_slice($items, 0, 50));
|
|
foreach ($items as $item) {
|
|
$wpdb->insert($table, [
|
|
'user_id' => $user_id,
|
|
'type' => sanitize_key((string) ($item['type'] ?? 'notice')),
|
|
'title' => sanitize_text_field((string) ($item['title'] ?? '')),
|
|
'description' => sanitize_text_field((string) ($item['desc'] ?? '')),
|
|
'target_url' => esc_url_raw((string) ($item['url'] ?? '')),
|
|
'is_read' => !empty($item['read']) ? 1 : 0,
|
|
'created_at' => (string) ($item['created_at'] ?? current_time('mysql', true)),
|
|
'read_at' => !empty($item['read']) ? current_time('mysql', true) : null,
|
|
], ['%d', '%s', '%s', '%s', '%s', '%d', '%s', '%s']);
|
|
}
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_add_user_notification')) :
|
|
/** 添加一条用户通知 */
|
|
function aksrt_add_user_notification(int $user_id, array $payload): void {
|
|
if ($user_id <= 0) return;
|
|
$type = sanitize_key((string) ($payload['type'] ?? 'notice'));
|
|
if (class_exists('AKSRT_Settings') && !AKSRT_Settings::notification_enabled($type)) {
|
|
return;
|
|
}
|
|
|
|
global $wpdb;
|
|
$table = class_exists('AKSRT_DB_Migrator') ? AKSRT_DB_Migrator::table('notification') : '';
|
|
$created_at = (string) ($payload['created_at'] ?? current_time('mysql', true));
|
|
|
|
if ($table === '') {
|
|
$items = aksrt_get_user_inbox_notifications($user_id);
|
|
array_unshift($items, [
|
|
'id' => isset($payload['id']) && $payload['id'] !== '' ? sanitize_text_field((string) $payload['id']) : uniqid('notif_', true),
|
|
'type' => $type,
|
|
'title' => sanitize_text_field((string) ($payload['title'] ?? '')),
|
|
'desc' => sanitize_text_field((string) ($payload['desc'] ?? '')),
|
|
'url' => esc_url_raw((string) ($payload['url'] ?? '')),
|
|
'read' => !empty($payload['read']) ? 1 : 0,
|
|
'created_at' => $created_at,
|
|
]);
|
|
aksrt_write_user_inbox_notifications($user_id, $items);
|
|
return;
|
|
}
|
|
|
|
$wpdb->insert($table, [
|
|
'user_id' => $user_id,
|
|
'type' => $type,
|
|
'title' => sanitize_text_field((string) ($payload['title'] ?? '')),
|
|
'description' => sanitize_text_field((string) ($payload['desc'] ?? '')),
|
|
'target_url' => esc_url_raw((string) ($payload['url'] ?? '')),
|
|
'is_read' => !empty($payload['read']) ? 1 : 0,
|
|
'created_at' => $created_at,
|
|
'read_at' => !empty($payload['read']) ? current_time('mysql', true) : null,
|
|
], ['%d', '%s', '%s', '%s', '%s', '%d', '%s', '%s']);
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_mark_user_notification_read')) :
|
|
/** 标记通知已读 */
|
|
function aksrt_mark_user_notification_read(int $user_id, string $notification_id = '', bool $mark_all = false): void {
|
|
if ($user_id <= 0) return;
|
|
global $wpdb;
|
|
$table = class_exists('AKSRT_DB_Migrator') ? AKSRT_DB_Migrator::table('notification') : '';
|
|
if ($table === '') {
|
|
$items = aksrt_get_user_inbox_notifications($user_id);
|
|
foreach ($items as &$item) {
|
|
if ($mark_all || (($item['id'] ?? '') === $notification_id)) {
|
|
$item['read'] = 1;
|
|
}
|
|
}
|
|
unset($item);
|
|
aksrt_write_user_inbox_notifications($user_id, $items);
|
|
return;
|
|
}
|
|
|
|
if ($mark_all) {
|
|
$wpdb->update(
|
|
$table,
|
|
['is_read' => 1, 'read_at' => current_time('mysql', true)],
|
|
['user_id' => $user_id, 'is_read' => 0],
|
|
['%d', '%s'],
|
|
['%d', '%d']
|
|
);
|
|
return;
|
|
}
|
|
|
|
$wpdb->update(
|
|
$table,
|
|
['is_read' => 1, 'read_at' => current_time('mysql', true)],
|
|
['id' => absint($notification_id), 'user_id' => $user_id],
|
|
['%d', '%s'],
|
|
['%d', '%d']
|
|
);
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_delete_user_notification')) :
|
|
/** 删除一条用户通知 */
|
|
function aksrt_delete_user_notification(int $user_id, string $notification_id): void {
|
|
if ($user_id <= 0 || $notification_id === '') return;
|
|
global $wpdb;
|
|
$table = class_exists('AKSRT_DB_Migrator') ? AKSRT_DB_Migrator::table('notification') : '';
|
|
if ($table === '') {
|
|
$items = aksrt_get_user_inbox_notifications($user_id);
|
|
$items = array_values(array_filter($items, static function ($item) use ($notification_id) {
|
|
return (string) ($item['id'] ?? '') !== $notification_id;
|
|
}));
|
|
aksrt_write_user_inbox_notifications($user_id, $items);
|
|
return;
|
|
}
|
|
$wpdb->delete($table, ['id' => absint($notification_id), 'user_id' => $user_id], ['%d', '%d']);
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_delete_user_notifications')) :
|
|
/** 批量删除用户通知 */
|
|
function aksrt_delete_user_notifications(int $user_id, array $notification_ids): void {
|
|
if ($user_id <= 0 || empty($notification_ids)) return;
|
|
$ids = array_values(array_filter(array_map('absint', $notification_ids), static function ($id) { return $id > 0; }));
|
|
if (empty($ids)) return;
|
|
|
|
global $wpdb;
|
|
$table = class_exists('AKSRT_DB_Migrator') ? AKSRT_DB_Migrator::table('notification') : '';
|
|
if ($table === '') {
|
|
$items = aksrt_get_user_inbox_notifications($user_id);
|
|
$items = array_values(array_filter($items, static function ($item) use ($ids) {
|
|
return !in_array(absint($item['id'] ?? 0), $ids, true);
|
|
}));
|
|
aksrt_write_user_inbox_notifications($user_id, $items);
|
|
return;
|
|
}
|
|
|
|
$wpdb->query(
|
|
"DELETE FROM {$table} WHERE user_id = " . (int) $user_id . " AND id IN (" . implode(',', $ids) . ")"
|
|
);
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_get_user_unread_notification_count')) :
|
|
/** 获取用户未读通知数 */
|
|
function aksrt_get_user_unread_notification_count(int $user_id = 0): int {
|
|
$items = aksrt_get_user_inbox_notifications($user_id);
|
|
$count = 0;
|
|
foreach ($items as $item) {
|
|
if (empty($item['read'])) $count++;
|
|
}
|
|
return $count;
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_get_user_tab_badge_count')) :
|
|
/** user 底部 Tab 徽标计数:未读持久化通知 + 即时状态提醒 */
|
|
function aksrt_get_user_tab_badge_count(int $user_id = 0): int {
|
|
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
|
if ($user_id <= 0) {
|
|
return 0;
|
|
}
|
|
if (class_exists('AKSRT_Settings') && !AKSRT_Settings::notification_user_badge_enabled()) {
|
|
return 0;
|
|
}
|
|
|
|
$count = aksrt_get_user_unread_notification_count($user_id);
|
|
if (class_exists('AKSRT_Settings') && AKSRT_Settings::notification_badge_include_stateful()) {
|
|
$count += aksrt_get_user_notification_count($user_id);
|
|
}
|
|
return $count;
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_get_user_all_notifications')) :
|
|
/** 获取用户完整通知列表(持久化通知 + 即时提醒) */
|
|
function aksrt_get_user_all_notifications(int $user_id = 0): array {
|
|
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
|
|
if ($user_id <= 0) return [];
|
|
|
|
$inbox = aksrt_get_user_inbox_notifications($user_id);
|
|
$alerts = aksrt_get_user_notifications($user_id);
|
|
|
|
$normalized_alerts = [];
|
|
foreach ($alerts as $alert) {
|
|
$normalized_alerts[] = [
|
|
'id' => 'state_' . sanitize_key((string) ($alert['type'] ?? 'notice')),
|
|
'type' => sanitize_key((string) ($alert['type'] ?? 'notice')),
|
|
'title' => sanitize_text_field((string) ($alert['title'] ?? '')),
|
|
'desc' => sanitize_text_field((string) ($alert['desc'] ?? '')),
|
|
'url' => esc_url_raw((string) ($alert['url'] ?? '')),
|
|
'read' => 0,
|
|
'created_at' => current_time('mysql', true),
|
|
'count' => max(0, (int) ($alert['count'] ?? 0)),
|
|
'stateful' => 1,
|
|
];
|
|
}
|
|
|
|
return array_merge($inbox, $normalized_alerts);
|
|
}
|
|
endif;
|
|
|
|
add_action('wp_ajax_aksrt_mark_notification_read', function () {
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error(['message' => __('请先登录', 'aksrt')], 401);
|
|
}
|
|
|
|
$nonce = isset($_POST['nonce']) ? (string) $_POST['nonce'] : '';
|
|
if (!wp_verify_nonce($nonce, 'aksrt_public_nonce')) {
|
|
wp_send_json_error(['message' => __('安全验证失败', 'aksrt')], 403);
|
|
}
|
|
|
|
$notification_id = sanitize_text_field((string) ($_POST['notification_id'] ?? ''));
|
|
$mark_all = !empty($_POST['mark_all']);
|
|
aksrt_mark_user_notification_read(get_current_user_id(), $notification_id, $mark_all);
|
|
wp_send_json_success([
|
|
'unread' => aksrt_get_user_unread_notification_count(get_current_user_id()),
|
|
]);
|
|
});
|
|
|
|
add_action('wp_ajax_aksrt_delete_notification', function () {
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error(['message' => __('请先登录', 'aksrt')], 401);
|
|
}
|
|
|
|
$nonce = isset($_POST['nonce']) ? (string) $_POST['nonce'] : '';
|
|
if (!wp_verify_nonce($nonce, 'aksrt_public_nonce')) {
|
|
wp_send_json_error(['message' => __('安全验证失败', 'aksrt')], 403);
|
|
}
|
|
|
|
$notification_id = sanitize_text_field((string) ($_POST['notification_id'] ?? ''));
|
|
if ($notification_id === '') {
|
|
wp_send_json_error(['message' => __('参数错误', 'aksrt')], 400);
|
|
}
|
|
|
|
aksrt_delete_user_notification(get_current_user_id(), $notification_id);
|
|
wp_send_json_success([
|
|
'unread' => aksrt_get_user_unread_notification_count(get_current_user_id()),
|
|
]);
|
|
});
|
|
|
|
add_action('wp_ajax_aksrt_delete_notifications', function () {
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error(['message' => __('请先登录', 'aksrt')], 401);
|
|
}
|
|
|
|
$nonce = isset($_POST['nonce']) ? (string) $_POST['nonce'] : '';
|
|
if (!wp_verify_nonce($nonce, 'aksrt_public_nonce')) {
|
|
wp_send_json_error(['message' => __('安全验证失败', 'aksrt')], 403);
|
|
}
|
|
|
|
$ids = isset($_POST['notification_ids']) ? (array) $_POST['notification_ids'] : [];
|
|
aksrt_delete_user_notifications(get_current_user_id(), $ids);
|
|
wp_send_json_success([
|
|
'unread' => aksrt_get_user_unread_notification_count(get_current_user_id()),
|
|
]);
|
|
});
|
|
|
|
add_action('wp_ajax_aksrt_check_new_notifications', function () {
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error(['message' => __('请先登录', 'aksrt')], 401);
|
|
}
|
|
|
|
$nonce = isset($_POST['nonce']) ? (string) $_POST['nonce'] : '';
|
|
if (!wp_verify_nonce($nonce, 'aksrt_public_nonce')) {
|
|
wp_send_json_error(['message' => __('安全验证失败', 'aksrt')], 403);
|
|
}
|
|
|
|
$unread = aksrt_get_user_unread_notification_count(get_current_user_id());
|
|
wp_send_json_success([
|
|
'count' => $unread,
|
|
'unread' => $unread,
|
|
]);
|
|
});
|
|
add_action('wp_insert_comment', function ($comment_id, $comment) {
|
|
if (!$comment instanceof WP_Comment) return;
|
|
if ((int) $comment->comment_parent <= 0) return;
|
|
if ((int) $comment->comment_approved !== 1) return;
|
|
if (get_comment_meta($comment_id, 'aksrt_reply_notified', true)) return;
|
|
|
|
$parent = get_comment((int) $comment->comment_parent);
|
|
if (!$parent instanceof WP_Comment) return;
|
|
$target_user_id = (int) $parent->user_id;
|
|
if ($target_user_id <= 0 || $target_user_id === (int) $comment->user_id) return;
|
|
|
|
$post_id = (int) $comment->comment_post_ID;
|
|
$url = get_comment_link($comment);
|
|
aksrt_add_user_notification($target_user_id, [
|
|
'type' => 'comment_reply',
|
|
'title' => __('评论收到回复', 'aksrt'),
|
|
'desc' => sprintf(__('“%s” 回复了你的评论。', 'aksrt'), get_comment_author($comment)),
|
|
'url' => $url ?: get_permalink($post_id),
|
|
]);
|
|
update_comment_meta($comment_id, 'aksrt_reply_notified', 1);
|
|
}, 20, 2);
|
|
|
|
add_action('transition_comment_status', function ($new_status, $old_status, $comment) {
|
|
if (!$comment instanceof WP_Comment) return;
|
|
if ($new_status !== 'approve' || $old_status === 'approve') return;
|
|
|
|
$comment_owner_id = (int) $comment->user_id;
|
|
if ($comment_owner_id > 0 && !get_comment_meta($comment->comment_ID, 'aksrt_approved_notified', true)) {
|
|
aksrt_add_user_notification($comment_owner_id, [
|
|
'type' => 'comment_approved',
|
|
'title' => __('评论已通过审核', 'aksrt'),
|
|
'desc' => __('你的评论已通过审核,现已公开展示。', 'aksrt'),
|
|
'url' => get_comment_link($comment),
|
|
]);
|
|
update_comment_meta($comment->comment_ID, 'aksrt_approved_notified', 1);
|
|
}
|
|
|
|
if ((int) $comment->comment_parent <= 0) return;
|
|
if (get_comment_meta($comment->comment_ID, 'aksrt_reply_notified', true)) return;
|
|
|
|
$parent = get_comment((int) $comment->comment_parent);
|
|
if (!$parent instanceof WP_Comment) return;
|
|
$target_user_id = (int) $parent->user_id;
|
|
if ($target_user_id <= 0 || $target_user_id === (int) $comment->user_id) return;
|
|
|
|
aksrt_add_user_notification($target_user_id, [
|
|
'type' => 'comment_reply',
|
|
'title' => __('评论收到回复', 'aksrt'),
|
|
'desc' => sprintf(__('“%s” 回复了你的评论。', 'aksrt'), get_comment_author($comment)),
|
|
'url' => get_comment_link($comment),
|
|
]);
|
|
update_comment_meta($comment->comment_ID, 'aksrt_reply_notified', 1);
|
|
}, 20, 3);
|
|
|
|
add_action('aksrt_credits_added', function ($user_id, $delta, $reason, $new_balance) {
|
|
if ($user_id <= 0 || $delta <= 0) return;
|
|
aksrt_add_user_notification((int) $user_id, [
|
|
'type' => 'credits_added',
|
|
'title' => __('积分增加', 'aksrt'),
|
|
'desc' => sprintf(__('积分变动:+%1$d,当前余额 %2$d。', 'aksrt'), (int) $delta, (int) $new_balance),
|
|
'url' => aksrt_get_user_center_url('credits'),
|
|
]);
|
|
}, 10, 4);
|
|
|
|
add_action('aksrt_credits_deducted', function ($user_id, $cost, $reason, $new_balance) {
|
|
if ($user_id <= 0 || $cost <= 0) return;
|
|
aksrt_add_user_notification((int) $user_id, [
|
|
'type' => 'credits_deducted',
|
|
'title' => __('积分扣减', 'aksrt'),
|
|
'desc' => sprintf(__('积分变动:-%1$d,当前余额 %2$d。', 'aksrt'), (int) $cost, (int) $new_balance),
|
|
'url' => aksrt_get_user_center_url('credits'),
|
|
]);
|
|
}, 10, 4);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|