Files
wordpress-theme-aksrt/inc/classes/class-aksrt-follow.php
T
kate522 15a883eb54 feat(credits): free points tasks matrix, day cap, and tasks tab
Add AKSRT_Points_Free for catalog/day-max/daily detail, wire the full
earn matrix (login, post, like, favorite, follow, comment, forum),
expose 积分任务 + 每日详情 tabs, and expand admin free-task settings.
2026-07-16 16:29:15 +08:00

184 lines
5.2 KiB
PHP

<?php
/**
* AKSRT Follow — 关注系统
*
* 使用专用表 {prefix}aksrt_follow 存储关注关系。
* 支持:关注、取消关注、计数、是否已关注。
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Follow {
private static $instance = null;
public static function get_instance(): self {
if (null === self::$instance) self::$instance = new self();
return self::$instance;
}
private function table(): string {
return AKSRT_DB_Migrator::table('follow');
}
/**
* 关注用户
*
* @param int $follower_id 关注者 ID
* @param int $following_id 被关注者 ID
* @return bool
*/
public function follow(int $follower_id, int $following_id): bool {
if ($follower_id <= 0 || $following_id <= 0 || $follower_id === $following_id) {
return false;
}
// 已关注则跳过
if ($this->is_following($follower_id, $following_id)) {
return true;
}
global $wpdb;
$result = $wpdb->insert($this->table(), [
'follower_id' => $follower_id,
'following_id' => $following_id,
'created_at' => current_time('mysql'),
], ['%d', '%d', '%s']);
if ($result === false) {
return false;
}
do_action('aksrt_user_followed', $follower_id, $following_id);
return true;
}
/**
* 取消关注
*/
public function unfollow(int $follower_id, int $following_id): bool {
if ($follower_id <= 0 || $following_id <= 0) return false;
global $wpdb;
$result = $wpdb->delete($this->table(), [
'follower_id' => $follower_id,
'following_id' => $following_id,
], ['%d', '%d']);
return $result !== false;
}
/**
* 切换关注状态
*
* @return bool true=已关注, false=已取消
*/
public function toggle(int $follower_id, int $following_id): bool {
if ($this->is_following($follower_id, $following_id)) {
$this->unfollow($follower_id, $following_id);
return false;
}
$this->follow($follower_id, $following_id);
return true;
}
/**
* 是否已关注
*/
public function is_following(int $follower_id, int $following_id): bool {
if ($follower_id <= 0 || $following_id <= 0) return false;
global $wpdb;
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM {$this->table()} WHERE follower_id = %d AND following_id = %d LIMIT 1",
$follower_id, $following_id
));
return (int) $exists > 0;
}
/**
* 获取粉丝数(谁关注了 target_id)
*/
public function get_follower_count(int $user_id): int {
if ($user_id <= 0) return 0;
global $wpdb;
return (int) $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$this->table()} WHERE following_id = %d",
$user_id
));
}
/**
* 获取关注数(target_id 关注了谁)
*/
public function get_following_count(int $user_id): int {
if ($user_id <= 0) return 0;
global $wpdb;
return (int) $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$this->table()} WHERE follower_id = %d",
$user_id
));
}
/**
* 获取粉丝列表
*/
public function get_followers(int $user_id, int $page = 1, int $per_page = 20): array {
return $this->get_user_list($user_id, 'following_id', $page, $per_page);
}
/**
* 获取关注列表
*/
public function get_following(int $user_id, int $page = 1, int $per_page = 20): array {
return $this->get_user_list($user_id, 'follower_id', $page, $per_page);
}
/**
* 通用用户列表查询
*/
private function get_user_list(int $user_id, string $where_field, int $page, int $per_page): array {
global $wpdb;
$other_field = $where_field === 'follower_id' ? 'following_id' : 'follower_id';
$offset = max(0, ($page - 1) * $per_page);
$total = (int) $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$this->table()} WHERE {$where_field} = %d",
$user_id
));
$rows = $wpdb->get_results($wpdb->prepare(
"SELECT {$other_field} as user_id, created_at
FROM {$this->table()}
WHERE {$where_field} = %d
ORDER BY created_at DESC
LIMIT %d OFFSET %d",
$user_id, $per_page, $offset
), ARRAY_A);
$items = [];
foreach ((array) $rows as $row) {
$uid = (int) $row['user_id'];
$user = get_userdata($uid);
$items[] = [
'user_id' => $uid,
'display_name' => $user ? $user->display_name : '',
'avatar_url' => $user ? get_avatar_url($uid, ['size' => 48]) : '',
'created_at' => $row['created_at'] ?? '',
];
}
return [
'items' => $items,
'total' => $total,
'page' => $page,
'total_pages' => max(1, (int) ceil($total / $per_page)),
];
}
}