Files
wordpress-theme-aksrt/inc/classes/settings/class-aksrt-settings-capabilities.php
T

275 lines
15 KiB
PHP

<?php
/**
* Settings capability/security helper.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Settings_Capabilities {
/**
* Capability definitions registry.
*
* @return array<string, array{label:string, roles?:string[], exclude_roles?:string[], default?:array<string,mixed>}>
*/
public static function cap_definitions(): array {
return [
'user_report' => ['label' => __('举报其它用户', 'aksrt'), 'default' => ['logged' => true]],
'balance_transfer' => ['label' => __('余额转账给其他用户', 'aksrt'), 'exclude_roles' => ['all']],
'points_transfer' => ['label' => __('积分转账给其他用户', 'aksrt'), 'exclude_roles' => ['all']],
'set_user_ban' => ['label' => __('设置用户封禁状态', 'aksrt'), 'roles' => ['cat_moderator'], 'default' => ['cat_moderator' => true]],
'medal_manually_set' => ['label' => __('为用户授予徽章', 'aksrt'), 'roles' => ['cat_moderator'], 'default' => ['cat_moderator' => true]],
'new_post_add' => ['label' => __('发布新文章', 'aksrt'), 'default' => ['logged' => true]],
'new_post_audit_no' => ['label' => __('投稿无需审核直接发布', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_audit_no_manual' => ['label' => __('无需人工审核直接发布', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_upload_img' => ['label' => __('投稿允许上传图片', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_upload_video' => ['label' => __('投稿允许上传视频', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_iframe_video' => ['label' => __('投稿允许插入 iframe 视频', 'aksrt'), 'exclude_roles' => ['all'], 'default' => ['logged' => true]],
'new_post_upload_file' => ['label' => __('投稿允许上传文件', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_hide' => ['label' => __('投稿允许发布隐藏内容', 'aksrt'), 'default' => ['logged' => true]],
'new_post_image_cover' => ['label' => __('发帖允许设置图片封面', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_slide_cover' => ['label' => __('允许设置幻灯片封面', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_video_cover' => ['label' => __('允许设置视频封面', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_pay' => ['label' => __('投稿允许设置付费内容', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_pay_download' => ['label' => __('投稿允许设置付费下载', 'aksrt'), 'exclude_roles' => ['all']],
'new_post_edit' => ['label' => __('修改自己发布的投稿', 'aksrt'), 'exclude_roles' => ['all'], 'default' => ['logged' => true]],
'new_post_delete' => ['label' => __('删除自己发布的投稿', 'aksrt'), 'exclude_roles' => ['all']],
'comment_view' => ['label' => __('查看评论', 'aksrt'), 'default' => ['all' => true]],
'comment_edit' => ['label' => __('修改自己发布的评论', 'aksrt'), 'exclude_roles' => ['all'], 'default' => ['logged' => true]],
'comment_delete' => ['label' => __('删除自己发布的评论', 'aksrt'), 'exclude_roles' => ['all']],
'comment_audit_no' => ['label' => __('评论无需审核直接发布', 'aksrt'), 'exclude_roles' => ['all']],
'comment_audit_no_manual' => ['label' => __('评论无需人工审核', 'aksrt'), 'exclude_roles' => ['all']],
'comment_set_topping_my_post' => ['label' => __('置顶自己文章下的评论', 'aksrt'), 'exclude_roles' => ['all'], 'default' => ['moderator' => true, 'plate_author' => true, 'cat_moderator' => true]],
'comment_set_topping_other' => ['label' => __('置顶管理帖子下的评论', 'aksrt'), 'roles' => ['moderator', 'plate_author', 'cat_moderator'], 'default' => ['cat_moderator' => true]],
'comment_edit_my_post' => ['label' => __('修改自己文章下的评论', 'aksrt'), 'exclude_roles' => ['all']],
'comment_edit_other' => ['label' => __('修改管理帖子下的评论', 'aksrt'), 'roles' => ['moderator', 'plate_author', 'cat_moderator'], 'default' => ['cat_moderator' => true]],
'comment_audit_my_post' => ['label' => __('审核自己文章下的评论', 'aksrt'), 'exclude_roles' => ['all'], 'default' => ['moderator' => true, 'plate_author' => true, 'cat_moderator' => true]],
'comment_audit_other' => ['label' => __('审核管理帖子下的评论', 'aksrt'), 'roles' => ['moderator', 'plate_author', 'cat_moderator'], 'default' => ['moderator' => true, 'plate_author' => true, 'cat_moderator' => true]],
'comment_delete_my_post' => ['label' => __('删除自己文章下的评论', 'aksrt'), 'exclude_roles' => ['all']],
'comment_delete_other' => ['label' => __('删除管理帖子下的评论', 'aksrt'), 'roles' => ['moderator', 'plate_author', 'cat_moderator'], 'default' => ['cat_moderator' => true]],
];
}
/**
* All role columns in the capability matrix.
*/
public static function cap_role_columns(): array {
return ['all', 'logged', 'level', 'vip', 'auth', 'moderator', 'plate_author', 'cat_moderator'];
}
/**
* Read the user_caps matrix from settings.
*
* @return array<string, array<string, mixed>>
*/
public static function get_user_capabilities(): array {
$s = AKSRT_Settings::get_all();
$stored = is_array($s['user_caps'] ?? null) ? $s['user_caps'] : [];
$defs = self::cap_definitions();
$cols = self::cap_role_columns();
$result = [];
foreach ($defs as $cap_id => $def) {
$defaults = $def['default'] ?? [];
$excludes = $def['exclude_roles'] ?? [];
$only_roles = $def['roles'] ?? null;
$row = [];
foreach ($cols as $col) {
if ($only_roles !== null && !in_array($col, $only_roles, true) && !in_array($col, ['all', 'logged', 'level', 'vip', 'auth'], true)) {
$row[$col] = false;
continue;
}
if (in_array($col, $excludes, true)) {
$row[$col] = false;
continue;
}
if (isset($stored[$cap_id][$col])) {
$val = $stored[$cap_id][$col];
$row[$col] = in_array($col, ['level', 'vip'], true) ? (int) $val : (bool) $val;
} else {
$row[$col] = $defaults[$col] ?? (in_array($col, ['level', 'vip'], true) ? -1 : false);
}
}
$result[$cap_id] = $row;
}
return $result;
}
/**
* Resolve whether a user has a specific capability.
*/
public static function user_can(string $cap, int $user_id = 0, ?int $context = null): bool {
if ($user_id > 0 && user_can($user_id, 'manage_options')) {
return true;
}
$caps = self::get_user_capabilities();
if (!isset($caps[$cap])) {
return false;
}
$row = $caps[$cap];
if (!empty($row['all'])) {
return true;
}
if ($user_id <= 0) {
return false;
}
if (!empty($row['logged'])) {
return true;
}
$level_threshold = (int) ($row['level'] ?? -1);
if ($level_threshold >= 0) {
$user_level = (int) get_user_meta($user_id, 'aksrt_user_level', true);
if ($user_level >= $level_threshold) {
return true;
}
}
$vip_threshold = (int) ($row['vip'] ?? -1);
if ($vip_threshold >= 0) {
$user_vip = (int) get_user_meta($user_id, 'aksrt_vip_level', true);
if ($user_vip >= $vip_threshold) {
return true;
}
}
if (!empty($row['auth'])) {
$verify_status = get_user_meta($user_id, 'aksrt_user_verify_status', true);
if ($verify_status === 'verified') {
return true;
}
}
$forum = class_exists('AKSRT_Forum') ? AKSRT_Forum::get_instance() : null;
if (!empty($row['moderator']) && $forum && $context > 0) {
if ($forum->get_user_plate_tier($user_id, $context) >= AKSRT_Forum::TIER_MODERATOR) {
return true;
}
}
if (!empty($row['plate_author']) && $forum && $context > 0) {
if ($forum->get_user_plate_tier($user_id, $context) >= AKSRT_Forum::TIER_PLATE_AUTHOR) {
return true;
}
}
if (!empty($row['cat_moderator']) && $forum) {
if ($context > 0) {
if ($forum->get_user_plate_tier($user_id, $context) >= AKSRT_Forum::TIER_CAT_MOD) {
return true;
}
} else {
if (method_exists($forum, 'is_cat_moderator_anywhere') && $forum->is_cat_moderator_anywhere($user_id)) {
return true;
}
}
}
return false;
}
/**
* 获取"网站安全"设置
*/
public static function get_security_settings(): array {
$s = AKSRT_Settings::get_all();
$verification_type = sanitize_key((string) ($s['user_verification_type'] ?? 'slider'));
$allowed_types = ['image', 'slider', 'tcaptcha', 'geetest', 'null'];
if (!in_array($verification_type, $allowed_types, true)) {
$verification_type = 'slider';
}
return [
'verification_type' => $verification_type,
'verification_comment_s' => !empty($s['verification_comment_s']),
'verification_newposts_s' => !empty($s['verification_newposts_s']),
'verification_bbspost_s' => !empty($s['verification_bbspost_s']),
'verification_links_s' => !empty($s['verification_links_s'] ?? true),
'verification_signin_exclude' => sanitize_text_field((string) ($s['verification_signin_exclude'] ?? '')),
'geetest_enabled' => !empty($s['geetest_enabled']),
'geetest_id' => sanitize_text_field((string) ($s['geetest_id'] ?? '')),
'geetest_key' => sanitize_text_field((string) ($s['geetest_key'] ?? '')),
'tcaptcha_enabled' => !empty($s['tcaptcha_enabled']),
'tcaptcha_appid' => sanitize_text_field((string) ($s['tcaptcha_appid'] ?? '')),
'tcaptcha_secret_key' => sanitize_text_field((string) ($s['tcaptcha_secret_key'] ?? '')),
'brush_limit_post' => [
'enabled' => !empty($s['brush_limit_post_enabled']),
'minutes_10' => (int) ($s['brush_limit_post_minutes_10'] ?? 20),
'day_1' => (int) ($s['brush_limit_post_day_1'] ?? 50),
],
'brush_limit_comment' => [
'enabled' => !empty($s['brush_limit_comment_enabled']),
'minutes_10' => (int) ($s['brush_limit_comment_minutes_10'] ?? 20),
'day_1' => (int) ($s['brush_limit_comment_day_1'] ?? 100),
],
'brush_limit_upload' => [
'enabled' => !empty($s['brush_limit_upload_enabled']),
'minutes_10' => (int) ($s['brush_limit_upload_minutes_10'] ?? 50),
'day_1' => (int) ($s['brush_limit_upload_day_1'] ?? 200),
],
'brush_limit_register' => [
'enabled' => !empty($s['brush_limit_register_enabled']),
'minutes_10' => (int) ($s['brush_limit_register_minutes_10'] ?? 20),
'day_1' => (int) ($s['brush_limit_register_day_1'] ?? 100),
],
'brush_limit_order' => [
'enabled' => !empty($s['brush_limit_order_enabled']),
'minutes_10' => (int) ($s['brush_limit_order_minutes_10'] ?? 30),
'day_1' => (int) ($s['brush_limit_order_day_1'] ?? 100),
],
'error_frequency_limit' => !empty($s['error_frequency_limit'] ?? true),
'user_disable_admin' => !empty($s['user_disable_admin'] ?? true),
'disabled_pingback' => !empty($s['disabled_pingback'] ?? true),
'disabled_xmlrpc' => !empty($s['disabled_xmlrpc'] ?? true),
'close_attachment_page' => !empty($s['close_attachment_page'] ?? true),
];
}
/**
* 获取"系统工具"设置
*/
public static function get_system_tools_settings(): array {
$s = AKSRT_Settings::get_all();
$time_format = sanitize_text_field((string) ($s['time_format'] ?? 'n月j日 H:i'));
return [
'remove_emoji' => !empty($s['remove_emoji'] ?? true),
'remove_open_sans' => !empty($s['remove_open_sans'] ?? true),
'remove_more_wp_head' => !empty($s['remove_more_wp_head'] ?? true),
'hide_admin_bar' => !empty($s['hide_admin_bar'] ?? true),
'remove_dashboard_widgets' => !empty($s['remove_dashboard_widgets'] ?? true),
'admin_frontend_set' => !empty($s['admin_frontend_set'] ?? true),
'display_wp_update' => !empty($s['display_wp_update'] ?? true),
'close_gutenberg' => !empty($s['close_gutenberg']),
'admin_user_del_fields' => !empty($s['admin_user_del_fields'] ?? true),
'split_upload_s' => !empty($s['split_upload_s'] ?? true),
'split_minimum_size' => max(4, min(100, (int) ($s['split_minimum_size'] ?? 20))),
'newfilename' => !empty($s['newfilename']),
'newfilename_type' => in_array($s['newfilename_type'] ?? 'time', ['random', 'time'], true)
? $s['newfilename_type'] : 'time',
'disabled_large_thumbnail' => !empty($s['disabled_large_thumbnail'] ?? true),
'disabled_autoembed' => !empty($s['disabled_autoembed'] ?? true),
'mce_float_toolbar' => [
'pc_s' => !empty($s['mce_float_toolbar_pc_s'] ?? true),
'm_s' => !empty($s['mce_float_toolbar_m_s'] ?? true),
],
'time_ago_s' => !empty($s['time_ago_s'] ?? true),
'time_format' => $time_format,
];
}
}