Files
wordpress-theme-aksrt/src/User/Home.php
T
2026-08-05 02:04:55 +08:00

268 lines
9.1 KiB
PHP

<?php
/**
* @package AKSRT
*/
namespace AKSRT\User;
defined('ABSPATH') || exit;
class Home {
private static $instance = null;
/** @var array Tab 注册表 */
private $tabs = [];
private function __construct() {}
public static function get_instance(): self {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function init(): void {
$this->register_default_tabs();
}
/**
* 注册默认公开 Tab
*/
private function register_default_tabs(): void {
$this->tabs = [
'posts' => [
'label' => __('文章', 'aksrt'),
'icon' => 'file-alt',
'priority' => 10,
],
'comments' => [
'label' => __('评论', 'aksrt'),
'icon' => 'comment',
'priority' => 20,
],
'favorites' => [
'label' => __('收藏', 'aksrt'),
'icon' => 'star',
'priority' => 30,
],
'credits' => [
'label' => class_exists('\AKSRT\Settings\Settings')
? sprintf(__('我的%s', 'aksrt'), \AKSRT\Settings\Settings::get_currency_name())
: __('我的积分', 'aksrt'),
'icon' => 'wallet',
'priority' => 40,
],
'follow' => [
'label' => __('粉丝', 'aksrt'),
'icon' => 'user-plus',
'priority' => 80,
],
];
/**
* 允许插件/子主题注册额外公开 Tab
*
* @param array $tabs Tab 注册表
*/
$this->tabs = apply_filters('aksrt_user_home_tabs', $this->tabs);
}
/**
* 获取 Tab 注册表
*/
public function get_tabs(): array {
return $this->tabs;
}
/**
* 获取当前用户主页实际可见的公开 Tab。
*/
public function get_visible_tabs(bool $is_own_profile = false): array {
$settings = class_exists('\AKSRT\Settings\Settings')
? \AKSRT\Settings\Settings::get_user_home_settings()
: [
'tabs' => ['posts', 'comments', 'favorites'],
];
$visible = [];
foreach ((array) ($settings['tabs'] ?? []) as $key) {
if (!isset($this->tabs[$key])) {
continue;
}
if ($key === 'credits' && (!$is_own_profile || !class_exists('\AKSRT\Settings\Settings') || !\AKSRT\Settings\Settings::credits_enabled())) {
continue;
}
$visible[$key] = $this->tabs[$key];
}
if (empty($visible)) {
foreach (['posts', 'comments', 'favorites'] as $fallback) {
if (isset($this->tabs[$fallback])) {
$visible[$fallback] = $this->tabs[$fallback];
}
}
}
return $visible;
}
/**
* 获取公开展示的身份信号(认证 / 等级 / 徽章)。
*
* @return array<int,array{label:string,icon:string,tone:string,icon_url?:string,type?:string,slug?:string,wear?:bool}>
*/
public function get_profile_signals(int $user_id): array {
if ($user_id <= 0 || !class_exists('\AKSRT\Settings\Settings')) {
return [];
}
$settings = \AKSRT\Settings\Settings::get_user_identity_settings();
$signals = [];
if (!empty($settings['verify']['enabled']) && !empty($settings['verify']['public_display']) && $this->is_user_verified($user_id, $settings['verify'])) {
$info = class_exists('AKSRT\\User\\AuthApply') ? AuthApply::get_auth_info($user_id) : [];
$application = class_exists('AKSRT\\User\\AuthApply') ? AuthApply::get_apply_payload($user_id) : [];
$type = sanitize_key((string) ($info['type'] ?? $application['type'] ?? ''));
$type_settings = is_array($settings['verify']['types'][$type] ?? null) ? $settings['verify']['types'][$type] : [];
$label = trim((string) ($type_settings['badge_text'] ?? $type_settings['label'] ?? ''));
if ($label === '') {
foreach ((array) ($settings['verify']['types'] ?? []) as $configured_type) {
if (is_array($configured_type) && !empty($configured_type['badge_text'])) {
$label = trim((string) $configured_type['badge_text']);
break;
}
}
}
$signals[] = [
'type' => 'verify',
'label' => $label,
'title' => $label,
'icon' => 'check-circle',
'icon_url' => get_theme_file_uri('/assets/img/user/user-certification.svg'),
'tone' => 'success',
];
}
if (!empty($settings['level']['enabled']) && !empty($settings['level']['public_display'])) {
$level = $this->get_user_level($user_id, $settings['level']);
if ($level > 0) {
$signals[] = [
'type' => 'level',
'label' => Level::get_level_name($level),
'title' => Level::get_level_name($level),
'icon' => 'layer-group',
'icon_url' => Level::get_level_icon_url($level),
'tone' => 'info',
];
}
}
if (!empty($settings['badge']['enabled']) && !empty($settings['badge']['public_display'])) {
$limit = max(1, (int) ($settings['badge']['limit'] ?? 3));
if (class_exists('AKSRT\\User\\Badges')) {
$list = Badges::list_for_user($user_id);
$badge_count = 0;
$done = false;
foreach ((array) ($list['categories'] ?? []) as $cat) {
foreach ((array) ($cat['items'] ?? []) as $item) {
if (empty($item['owned'])) {
continue;
}
if ($badge_count >= $limit) {
$done = true;
break;
}
$signals[] = [
'type' => 'badge',
'slug' => (string) ($item['slug'] ?? ''),
'label' => (string) ($item['label'] ?? ''),
'icon' => 'award',
'tone' => 'info',
'icon_url' => (string) ($item['icon_url'] ?? ''),
'wear' => !empty($item['wear']),
];
$badge_count++;
}
if ($done) {
break;
}
}
}
}
return $signals;
}
/**
* 获取公开治理提示。
*
* @return array{state:string,text:string}|array{}
*/
public function get_profile_notice(int $user_id): array {
if ($user_id <= 0 || !class_exists('\AKSRT\Settings\Settings')) {
return [];
}
$settings = \AKSRT\Settings\Settings::get_user_identity_settings();
if (empty($settings['report']['enabled']) || empty($settings['report']['public_notice'])) {
return [];
}
$state = sanitize_key((string) get_user_meta($user_id, 'aksrt_user_ban_state', true));
if (!in_array($state, ['muted', 'restricted', 'banned'], true)) {
return [];
}
return [
'state' => $state,
'text' => (string) $settings['report']['ban_notice_text'],
];
}
/**
* 公开主页是否显示举报入口。
*/
public function show_report_entry(): bool {
if (!class_exists('\AKSRT\Settings\Settings')) {
return false;
}
$settings = \AKSRT\Settings\Settings::get_user_identity_settings();
return !empty($settings['report']['enabled']) && !empty($settings['report']['public_entry']);
}
/**
* @param array{accept_email_verified:bool} $verify_settings
*/
private function is_user_verified(int $user_id, array $verify_settings): bool {
if (class_exists('\\AKSRT\\User\\AuthApply') && AuthApply::is_verified($user_id)) {
return true;
}
if (!empty($verify_settings['accept_email_verified']) && class_exists('\AKSRT\Auth\Service')) {
return \AKSRT\Auth\Service::user_is_email_verified($user_id);
}
return false;
}
/**
* @param array{source?:string,thresholds?:array<int,int>} $level_settings
*/
private function get_user_level(int $user_id, array $level_settings): int {
unset($level_settings);
return class_exists('AKSRT\\User\\Level') ? Level::get_level($user_id) : 0;
}
/**
* 判断当前页面是否为公开用户主页
*/
public static function is_page(): bool {
return function_exists('aksrt_is_user_home_page') && aksrt_is_user_home_page();
}
}