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.
184 lines
5.2 KiB
PHP
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)),
|
|
];
|
|
}
|
|
}
|