Files
wordpress-theme-aksrt/src/Admin/Schema/SchemaPermissions.php
T
kate522andClaude Opus 5 4c562428b4 feat(links): move friend links to native WordPress links with review flow
- enable the native Links manager and drop the custom friend-link option/REST path
- add per-page link settings for the friends template
- render link categories from get_bookmarks() with search and page-content options
- add a validated public link submission endpoint with logo upload, captcha, rate limiting and duplicate checks
- create pending links for review and notify administrators by email and in-app message
- add native Links admin pending count, columns and edit notes
- cover the new submission and cleanup contracts

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-05 19:54:33 +08:00

179 lines
13 KiB
PHP

<?php
/**
* @package Jio
*/
namespace Jio\Admin\Schema;
defined('ABSPATH') || exit;
class SchemaPermissions {
/**
* User type options for upload size limit rows.
*
* @return array<int, array{label:string, value:string}>
*/
private static function upload_user_type_options(): array {
$options = [];
foreach (\Jio\Attachment\UploadLimits::user_type_options() as $value => $label) {
$options[] = ['label' => $label, 'value' => $value];
}
return $options;
}
/**
* User type options for mime limit rows (adds the "all users" type).
*
* @return array<int, array{label:string, value:string}>
*/
private static function upload_mime_user_type_options(): array {
$options = [
['label' => __('所有用户', 'jio'), 'value' => 'all'],
];
foreach (\Jio\Attachment\UploadLimits::user_type_options() as $value => $label) {
$options[] = ['label' => $label, 'value' => $value];
}
return $options;
}
public static function build(): array {
$provider_meta = function_exists('jio_captcha_provider_metadata') ? jio_captcha_provider_metadata() : [];
$provider_options = [['label' => '关闭', 'value' => '']];
$provider_fields = [];
foreach ($provider_meta as $provider => $meta) {
$provider_options[] = [
'label' => (string) ($meta['label'] ?? $provider),
'value' => $provider,
];
$provider_fields[] = [
'key' => $provider,
'label' => (string) ($meta['label'] ?? $provider) . ' 配置',
'type' => 'custom',
'default' => function_exists('jio_captcha_provider_defaults') ? jio_captcha_provider_defaults($provider) : [],
'captcha_provider' => $provider,
];
}
return [
'domain' => 'permissions',
'title' => '功能与权限',
'sections' => [
'login' => [
'key' => 'login',
'title' => '人机验证',
'version' => '1.1.0',
'option_key' => 'jio_captcha_config',
'groups' => [
['key' => 'basic', 'title' => '基础开关', 'fields' => [
['key' => 'enabled', 'label' => '启用人机验证', 'type' => 'switch', 'default' => false],
['key' => 'active_provider', 'label' => '当前服务商', 'type' => 'radio', 'default' => '', 'dependsOn' => ['key' => 'enabled', 'value' => true], 'options' => $provider_options],
['key' => 'enabled_scenarios', 'label' => '启用场景', 'type' => 'checkbox', 'default' => [], 'dependsOn' => ['key' => 'enabled', 'value' => true], 'options' => [
['label' => '发表评论', 'value' => 'comment'],
['label' => '用户登录', 'value' => 'login'],
['label' => '用户注册', 'value' => 'register'],
['label' => '绑定第三方', 'value' => 'bind'],
['label' => '绑定手机', 'value' => 'bind_phone'],
['label' => '找回密码', 'value' => 'lostpassword'],
['label' => '修改密码', 'value' => 'change_password'],
['label' => '更改邮箱', 'value' => 'change_email'],
['label' => '资源下载', 'value' => 'download'],
['label' => '每日签到', 'value' => 'signin'],
['label' => '前台投稿', 'value' => 'front_submit'],
['label' => '打赏用户', 'value' => 'tip_user'],
['label' => '提交工单', 'value' => 'ticket_create'],
['label' => '回复工单', 'value' => 'ticket_reply'],
['label' => '友情链接申请', 'value' => 'friend_link'],
]],
]],
['key' => 'providers', 'title' => '服务商配置', 'dependsOn' => ['key' => 'enabled', 'value' => true], 'fields' => $provider_fields],
],
],
'attachment' => [
'key' => 'attachment',
'title' => '附件配置',
'version' => '1.2.0',
'option_key' => 'jio_settings',
'groups' => [
['key' => 'size-limits', 'title' => '上传大小限制', 'fields' => [
['key' => 'size_limit_notice', 'label' => '服务器环境提示', 'type' => 'notice', 'alertType' => 'warning', 'alertContent' => '设置上传大小,请考虑服务器负荷、硬盘,以及服务器最大能支持的范围。实际上传大小取「主题限制」与「PHP 环境限制」的较小值,超过 PHP 环境限制时请调整 php.ini 的 upload_max_filesize 与 post_max_size。'],
['key' => 'upload_img_size', 'label' => '前端图片上传限制', 'type' => 'repeater', 'default' => [
['type' => 'default', 'val' => 5],
['type' => 'admin', 'val' => 20],
], 'min' => 1, 'button_title' => '添加细分用户权限', 'help' => '投稿、评论、头像与资料卡背景图等前端场景允许上传的最大图片大小(单位 MB)。同一个用户满足多个条件则取最大值,「最小默认值」为所有人兜底。', 'fields' => [
['key' => 'type', 'label' => '用户类型', 'type' => 'select', 'default' => 'logged', 'options' => self::upload_user_type_options()],
['key' => 'val', 'label' => '可上传大小', 'type' => 'number', 'default' => 5, 'min' => 1, 'max' => 2048, 'unit' => 'M'],
]],
['key' => 'image_upload_multiple', 'label' => '图片批量上传最大数量', 'type' => 'number', 'default' => 6, 'min' => 0, 'max' => 100, 'unit' => '张', 'help' => '前端投稿、评论上传图片允许的单次批量上传数量(为 0 则不限制,为 1 则不能批量上传)。'],
['key' => 'upload_video_size', 'label' => '前端视频上传限制', 'type' => 'repeater', 'default' => [
['type' => 'default', 'val' => 30],
['type' => 'admin', 'val' => 2048],
], 'min' => 1, 'button_title' => '添加细分用户权限', 'help' => '前端允许上传的最大视频大小(单位 MB)。同一个用户满足多个条件则取最大值,必须包含最低默认值。', 'fields' => [
['key' => 'type', 'label' => '用户类型', 'type' => 'select', 'default' => 'logged', 'options' => self::upload_user_type_options()],
['key' => 'val', 'label' => '可上传大小', 'type' => 'number', 'default' => 30, 'min' => 1, 'max' => 2048, 'unit' => 'M'],
]],
['key' => 'upload_file_size', 'label' => '前端文件上传大小限制', 'type' => 'repeater', 'default' => [
['type' => 'default', 'val' => 30],
['type' => 'admin', 'val' => 2048],
], 'min' => 1, 'button_title' => '添加细分用户权限', 'help' => '前端允许上传的其他文件(不含视频和图片,建议大于视频图片)最大大小(单位 MB)。同一个用户满足多个条件则取最大值,必须包含最低默认值。', 'fields' => [
['key' => 'type', 'label' => '用户类型', 'type' => 'select', 'default' => 'logged', 'options' => self::upload_user_type_options()],
['key' => 'val', 'label' => '可上传大小', 'type' => 'number', 'default' => 30, 'min' => 1, 'max' => 2048, 'unit' => 'M'],
]],
]],
['key' => 'mime-limits', 'title' => '上传格式限制', 'fields' => [
['key' => 'mime_limit_notice', 'label' => '安全提示', 'type' => 'notice', 'alertType' => 'warning', 'alertContent' => '请添加文件的扩展名和 MIME 类型,用英文逗号分割。格式示例:mp3=audio/mpeg,jpg=image/jpeg。禁止的优先级大于允许。郑重提示:请勿允许上传 php、sh、exe 等可执行文件,会极大增加服务器被入侵攻击的风险。'],
['key' => 'upload_file_mimes', 'label' => '前端上传文件格式限制', 'type' => 'repeater', 'default' => [
['type' => 'admin', 'pattern' => 'allow', 'val' => 'svg=image/svg+xml'],
['type' => 'all', 'pattern' => 'allow', 'val' => ''],
], 'min' => 1, 'button_title' => '添加细分用户权限', 'help' => '根据不同的用户类型,添加额外允许或禁止上传的文件格式(禁止的优先级大于允许)。', 'fields' => [
['key' => 'type', 'label' => '用户类型', 'type' => 'select', 'default' => 'all', 'options' => self::upload_mime_user_type_options()],
['key' => 'pattern', 'label' => '规则', 'type' => 'select', 'default' => 'allow', 'options' => [
['label' => '允许', 'value' => 'allow'],
['label' => '禁止', 'value' => 'prohibit'],
]],
['key' => 'val', 'label' => '格式', 'type' => 'textarea', 'default' => '', 'rows' => 1, 'placeholder' => '如:svg=image/svg+xml,mp3=audio/mpeg'],
]],
]],
],
],
'moderation' => [
'key' => 'moderation',
'title' => '评论审核',
'version' => '1.0.0',
'option_key' => 'jio_moderation_config',
'groups' => [
['key' => 'basic', 'title' => '审核总开关', 'fields' => [
['key' => 'enabled', 'label' => '启用审核系统', 'type' => 'switch', 'default' => false],
]],
['key' => 'ai', 'title' => 'AI 审核', 'fields' => [
['key' => 'ai_enabled', 'label' => '启用 AI 审核', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'enabled', 'value' => true]],
['key' => 'ai_api_hint', 'label' => '审核 API 配置', 'type' => 'notice', 'alertType' => 'info', 'alertContent' => 'API 接入在「扩展 → API 内容审核」中统一配置;此处仅控制审核范围和策略。', 'dependsOn' => ['key' => 'ai_enabled', 'value' => true]],
['key' => 'ai_moderate_comments', 'label' => '用户评论', 'type' => 'switch', 'default' => true, 'dependsOn' => ['key' => 'ai_enabled', 'value' => true]],
['key' => 'ai_moderate_background', 'label' => '用户资料卡背景图', 'type' => 'switch', 'default' => true, 'dependsOn' => ['key' => 'ai_enabled', 'value' => true]],
['key' => 'auto_approve_low_risk', 'label' => '低风险自动通过', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'ai_enabled', 'value' => true]],
['key' => 'auto_reject_high_risk', 'label' => '高风险自动拒绝', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'ai_enabled', 'value' => true]],
['key' => 'low_risk_max_score', 'label' => '低风险上限', 'type' => 'number', 'default' => 35, 'min' => 0, 'max' => 100, 'dependsOn' => ['key' => 'ai_enabled', 'value' => true]],
['key' => 'high_risk_min_score', 'label' => '高风险下限', 'type' => 'number', 'default' => 80, 'min' => 0, 'max' => 100, 'dependsOn' => ['key' => 'ai_enabled', 'value' => true]],
]],
['key' => 'keywords', 'title' => '关键词拦截', 'fields' => [
['key' => 'blocked_keywords', 'label' => '屏蔽关键词列表', 'type' => 'textarea', 'default' => '', 'rows' => 4, 'dependsOn' => ['key' => 'enabled', 'value' => true]],
]],
['key' => 'rate-limit', 'title' => '频率限制', 'fields' => [
['key' => 'rate_limit_enabled', 'label' => '启用频率限制', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'enabled', 'value' => true]],
['key' => 'rate_limit_min_interval', 'label' => '最小间隔(秒)', 'type' => 'number', 'default' => 8, 'min' => 1, 'max' => 300, 'dependsOn' => ['key' => 'rate_limit_enabled', 'value' => true]],
['key' => 'rate_limit_max_per_hour', 'label' => '每小时上限', 'type' => 'number', 'default' => 15, 'min' => 1, 'max' => 200, 'dependsOn' => ['key' => 'rate_limit_enabled', 'value' => true]],
]],
],
],
'capabilities' => [
'key' => 'capabilities',
'title' => '基本权限',
'version' => '1.1.0',
'option_key' => 'jio_settings',
'groups' => [],
],
],
];
}
}