Files
wordpress-theme-aksrt/inc/classes/class-aksrt-settings.php
T
kate522 f3db6c89cc feat(shop): complete storefront archive, seller edit, revenue
Wire product cat/tag archives to settings-driven sort and AJAX paging,
seller product options/video/params editing, revenue withdraw form and
order review submit — finishing remaining shop frontend gaps after buy-path.
2026-07-12 10:38:02 +08:00

1304 lines
52 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* AKSRT Settings Helper
*
* 设置获取辅助函数,统一管理所有主题设置选项
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Settings {
use AKSRT_Settings_Domain_Groups;
use AKSRT_Settings_Display_Page_Groups;
use AKSRT_Settings_Credits_Payment_Groups;
use AKSRT_Settings_Category_Integration_Groups;
use AKSRT_Settings_Auth_Reader;
use AKSRT_Settings_Homepage_Reader;
private static $instance = null;
private function __construct() {}
public static function get_instance(): self {
if (null === self::$instance) self::$instance = new self();
return self::$instance;
}
public function init(): void {
// 注册设置API(可选)
add_action('customize_register', [$this, 'customizer']);
add_filter('get_site_icon_url', [self::class, 'filter_site_icon_url'], 10, 3);
add_action('init', [self::class, 'maybe_sync_native_site_icon'], 20);
// 搜索结果排除(search_no_page / search_exclude_cats)
add_action('pre_get_posts', [self::class, 'filter_search_query']);
// 全局列表默认排序(list_orderby)
add_action('pre_get_posts', [self::class, 'apply_list_orderby']);
// 全局列表每页数量(post_list_per_page)
add_action('pre_get_posts', [self::class, 'apply_list_per_page']);
// 文章发布/更新/删除时清理分类推荐缓存
add_action('save_post', [self::class, 'on_post_changed']);
add_action('delete_post', [self::class, 'on_post_changed']);
// 设置变更时清理 per-request memo
add_action('updated_option', [self::class, 'on_option_updated'], 10, 1);
add_action('added_option', [self::class, 'on_option_updated'], 10, 1);
add_action('deleted_option', [self::class, 'on_option_updated'], 10, 1);
}
/**
* Per-request memoization of merged settings.
*
* 同一请求内多次调用 get_all() 仅读 1 次 option。
* 后端写入 option 时通过 updated_option hook 失效。
*
* @var array|null
*/
private static $cached_all = null;
/**
* Option 变更时失效缓存(响应所有主题相关 option key)。
*/
public static function on_option_updated(string $option_name): void {
$tracked = array_merge(
['aksrt_settings'],
self::STANDALONE_OPTION_KEYS
);
if (in_array($option_name, $tracked, true)) {
self::$cached_all = null;
}
}
/**
* 文章变更时清理分类推荐缓存
*/
public static function on_post_changed(int $post_id): void {
if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) return;
$post = get_post($post_id);
if (!$post || $post->post_type !== 'post') return;
self::flush_category_recommend_cache();
}
// ============================================
// 设置读取方法
// ============================================
/** 获取全部设置(per-request memo) */
public static function get_all(): array {
if (self::$cached_all !== null) {
return self::$cached_all;
}
// Canonical theme settings live only in aksrt_settings.
// Operational configs (captcha/moderation/oauth/footer/etc.) stay standalone.
$settings = get_option('aksrt_settings', []);
if (!is_array($settings)) {
$settings = [];
}
self::$cached_all = $settings;
return $settings;
}
/**
* 显式刷新缓存(外部直接修改 option 后可调用)。
*/
public static function flush_settings_cache(): void {
self::$cached_all = null;
}
// ============================================
// Option Registry — domain/section → option key 映射
// ============================================
/**
* 所有独立 option key(非 aksrt_settings)。
* 用于导入导出完整性检查。
*/
public const STANDALONE_OPTION_KEYS = [
'aksrt_mail_smtp',
'aksrt_oauth',
'aksrt_captcha_config',
'aksrt_moderation_config',
'aksrt_footer_settings',
'aksrt_footer_tabbar',
'aksrt_floating_buttons',
'aksrt_credit_settings',
'aksrt_notification_settings',
'aksrt_friend_links',
'aksrt_banners',
'aksrt_category_recommend',
];
/**
* 包含 secret 字段的 option key — 空值保留旧值策略。
*/
public const SECRET_OPTION_KEYS = [
'aksrt_mail_smtp',
'aksrt_oauth',
];
/**
* 读取指定 domain/section 的配置(委托 Schema Provider)。
*
* @param string $domain 域名 (global, page_display, post_list, ...)
* @param string $section 分区名 (可为空,读取整个 domain)
* @return array
*/
public static function read_domain(string $domain, string $section = ''): array {
$provider = AKSRT_Admin_Schema_Provider::get_instance();
return $provider->read_settings($domain, $section);
}
/**
* 写入指定 domain/section 的配置(委托 Schema Provider)。
*
* 仅写入当前 section allowlist 中的字段,不会覆盖同 option 中其它 section 的字段。
* 写入后自动刷新 memo cache 并触发 action。
*
* @param string $domain 域名
* @param string $section 分区名
* @param array $data 要写入的数据
* @return bool
*/
public static function write_domain(string $domain, string $section, array $data): bool {
$provider = AKSRT_Admin_Schema_Provider::get_instance();
$result = $provider->write_settings($domain, $data, $section);
if ($result) {
self::flush_settings_cache();
$option_key = $provider->get_option_key($domain, $section);
do_action('aksrt_settings_domain_saved', $domain, $section, $option_key);
}
return $result;
}
/**
* 获取指定 domain/section 的默认值。
*/
public static function get_domain_defaults(string $domain, string $section = ''): array {
$provider = AKSRT_Admin_Schema_Provider::get_instance();
return $provider->get_defaults($domain, $section);
}
/**
* 重置指定 domain/section 到默认值。
*/
public static function reset_domain(string $domain, string $section = ''): bool {
$provider = AKSRT_Admin_Schema_Provider::get_instance();
$result = $provider->reset_to_defaults($domain, $section);
if ($result) {
self::flush_settings_cache();
do_action('aksrt_settings_domain_reset', $domain, $section);
}
return $result;
}
public static function get_value(string $key, $default = null) {
$settings = self::get_all();
return array_key_exists($key, $settings) ? $settings[$key] : $default;
}
/** 获取导航 Logo 宽度 */
public static function logo_width(): int {
$width = (int) self::get_value('logo_width', 150);
return max(50, min(400, $width));
}
/** 获取Favicon URL */
public static function custom_favicon_url(): string {
$favicon = (string) self::get_value('site_favicon', '');
return $favicon !== '' ? $favicon : '';
}
public static function favicon_url(): string {
$custom = self::custom_favicon_url();
if ($custom !== '') {
return $custom;
}
$site_icon = get_site_icon_url(512);
return $site_icon ? (string) $site_icon : self::default_asset_url('default-favicon.svg');
}
/** 获取About显示名 */
/**
* 让 SEO 设置中的 Favicon 覆盖 WordPress 原生 site_icon 输出链路。
*
* @param string $url
* @param int $size
* @param int $blog_id
* @return string
*/
public static function filter_site_icon_url($url, $size, $blog_id): string {
$custom = self::custom_favicon_url();
return $custom !== '' ? $custom : (string) $url;
}
/**
* 尝试把自定义 favicon 同步到 WordPress 原生 site_icon 选项。
*
* 仅当 URL 能映射到媒体库附件时才同步;外链仍通过 get_site_icon_url 过滤覆盖。
*/
public static function sync_native_site_icon(string $favicon_url): void {
$favicon_url = trim(esc_url_raw($favicon_url));
if ($favicon_url === '') {
return;
}
$attachment_id = attachment_url_to_postid($favicon_url);
if ($attachment_id > 0 && (int) get_option('site_icon', 0) !== $attachment_id) {
update_option('site_icon', $attachment_id);
}
}
/** 启动时对齐原生 site_icon,同步自定义 site_favicon 到原生 site_icon。 */
public static function maybe_sync_native_site_icon(): void {
$custom = self::custom_favicon_url();
if ($custom === '') {
return;
}
self::sync_native_site_icon($custom);
}
public static function about_display_name(): string {
$s = self::get_all();
return !empty($s['about_display_name']) ? $s['about_display_name'] : get_bloginfo('name');
}
/** 获取About简介 */
public static function about_bio(): string {
$s = self::get_all();
return !empty($s['about_bio']) ? $s['about_bio'] : get_bloginfo('description');
}
/** 获取About头像URL */
public static function about_avatar(): string {
$s = self::get_all();
return $s['about_avatar'] ?? ($s['admin_avatar_url'] ?? '');
}
/** 获取头像镜像源 */
public static function avatar_source(): string {
$source = sanitize_text_field((string) self::get_value('avatar_source', 'cn.cravatar.com'));
$allowed = ['cn.cravatar.com', 'cn.gravatar.com', 'gravatar.com'];
return in_array($source, $allowed, true) ? $source : 'cn.cravatar.com';
}
/** 获取SEO关键词 */
public static function seo_keywords(): string {
$s = self::get_all();
return $s['seo_keywords'] ?? '';
}
/** 获取自定义头部代码 */
public static function custom_head_code(): string {
$code = (string) self::get_value('head_code', '');
if ($code === '') {
$code = (string) self::get_value('custom_js_header', '');
}
return $code;
}
/** 获取自定义 CSS */
public static function custom_css(): string {
return (string) self::get_value('custom_css', '');
}
/** 获取自定义底部代码 */
public static function custom_footer_code(): string {
$code = (string) self::get_value('foot_code', '');
if ($code === '') {
$code = (string) self::get_value('custom_js_footer', '');
}
return $code;
}
/** 获取统计代码 */
public static function trackcode(): string {
return trim((string) self::get_value('trackcode', ''));
}
/** 获取搜索框占位文案 */
public static function search_placeholder(): string {
return AKSRT_Settings_Theme_Search::search_placeholder();
}
/** 获取搜索模式 */
public static function search_mode(): string {
return AKSRT_Settings_Theme_Search::search_mode();
}
/** 是否启用搜索历史 */
public static function search_history_enabled(): bool {
return AKSRT_Settings_Theme_Search::search_history_enabled();
}
/** 是否启用热门搜索 */
public static function hot_search_enabled(): bool {
return AKSRT_Settings_Theme_Search::hot_search_enabled();
}
/** 获取热门搜索关键词 */
public static function hot_search_keywords(): array {
return AKSRT_Settings_Theme_Search::hot_search_keywords();
}
/** 热门搜索标题(留空使用默认) */
public static function search_popular_title(): string {
return AKSRT_Settings_Theme_Search::search_popular_title();
}
/** 置顶搜索词(始终显示在最前面) */
public static function search_popular_sticky(): array {
return AKSRT_Settings_Theme_Search::search_popular_sticky();
}
/** 是否启用搜索建议 */
public static function search_suggestions_enabled(): bool {
return AKSRT_Settings_Theme_Search::search_suggestions_enabled();
}
/** 是否在搜索面板显示热门文章 */
public static function search_posts_enabled(): bool {
return AKSRT_Settings_Theme_Search::search_posts_enabled();
}
/** 搜索结果是否排除页面 */
public static function search_no_page(): bool {
return AKSRT_Settings_Theme_Search::search_no_page();
}
/** 获取搜索排除分类 ID 列表 */
public static function search_exclude_cats(): array {
return AKSRT_Settings_Theme_Search::search_exclude_cats();
}
/** 是否启用分类搜索选择器 */
public static function search_cat_enabled(): bool {
return AKSRT_Settings_Theme_Search::search_cat_enabled();
}
/** 获取默认搜索分类 */
public static function search_cat_in(): string {
return AKSRT_Settings_Theme_Search::search_cat_in();
}
/** 是否显示更多分类 */
public static function search_more_cat_obj(): bool {
return AKSRT_Settings_Theme_Search::search_more_cat_obj();
}
/** 是否启用自定义搜索匹配范围 */
public static function search_custom_key_enabled(): bool {
return AKSRT_Settings_Theme_Search::search_custom_key_enabled();
}
/** 获取自定义搜索匹配字段列表 */
public static function search_custom_key(): array {
return AKSRT_Settings_Theme_Search::search_custom_key();
}
/** 是否启用搜索结果 taxonomy 筛选 */
public static function search_facets_enabled(): bool {
return AKSRT_Settings_Theme_Search::search_facets_enabled();
}
/** 获取搜索结果筛选 taxonomy 排序列表 */
public static function search_facets_order(): array {
return AKSRT_Settings_Theme_Search::search_facets_order();
}
/**
* Meilisearch integration configuration.
*
* @return array{enabled:bool,api_url:string,api_key:string,index_prefix:string,synonyms:array}
*/
public static function get_meilisearch_config(): array {
return AKSRT_Settings_Theme_Search::get_meilisearch_config();
}
/**
* pre_get_posts 过滤:应用搜索排除配置
* - search_no_page: 排除页面
* - search_exclude_cats: 排除指定分类
*/
public static function filter_search_query($query): void {
AKSRT_Settings_Theme_Search::filter_search_query($query);
}
/**
* pre_get_posts: apply global list_orderby on archive/tag/category/search pages.
*
* Only fires when no explicit orderby is set by URL params or other hooks.
*/
public static function apply_list_orderby($query): void {
AKSRT_Settings_Post_Display::apply_list_orderby($query);
}
/**
* 获取搜索内容类型配置
*
* @return array{types: string[], default: string}
*/
public static function get_search_content_types(): array {
return AKSRT_Settings_Theme_Search::get_search_content_types();
}
/** 默认主题模式 (white-theme / dark-theme / time-auto) */
public static function theme_mode(): string {
return AKSRT_Settings_Theme_Search::theme_mode();
}
/** 主题模式 → JS 可消费的简化值 (light / dark / time-auto) */
public static function theme_mode_js_value(): string {
return AKSRT_Settings_Theme_Search::theme_mode_js_value();
}
/** time-auto:对齐 zibll 早晚 8 点自动切换语义。 */
public static function time_auto_theme_mode(): string {
return AKSRT_Settings_Theme_Search::time_auto_theme_mode();
}
/** 首屏主题模式:优先消费 zibll 兼容 cookie,回退后台默认值。 */
public static function initial_theme_mode(): string {
return AKSRT_Settings_Theme_Search::initial_theme_mode();
}
/** 获取主题色 */
public static function primary_color(): string {
return AKSRT_Settings_Theme_Search::primary_color();
}
/** 获取主题皮肤预设 hex(解析 palette 选项为 #hex 格式) */
public static function theme_skin(): string {
return AKSRT_Settings_Theme_Search::theme_skin();
}
/** 获取暗色模式独立主题色 */
public static function dark_primary_color(): string {
return AKSRT_Settings_Theme_Search::dark_primary_color();
}
/** 获取主题切换按钮显示位置列表 */
public static function get_theme_mode_button_positions(): array {
return AKSRT_Settings_Theme_Search::get_theme_mode_button_positions();
}
/** 获取最终生效的主题色(skin 优先于 custom primary_color) */
public static function resolved_primary_color(): string {
return AKSRT_Settings_Theme_Search::resolved_primary_color();
}
/** 获取全局圆角 */
public static function border_radius(): int {
return AKSRT_Settings_Theme_Search::border_radius();
}
/** 获取卡片圆角值(独立设置优先,否则 border_radius + 4) */
public static function card_radius(): int {
return AKSRT_Settings_Theme_Search::card_radius();
}
/** 全站加载动画开关 */
public static function is_qj_loading_enabled(): bool {
return AKSRT_Settings_Theme_Search::is_qj_loading_enabled();
}
/** 加载动画样式 (no1–no10) */
public static function get_qj_loading_style(): string {
return AKSRT_Settings_Theme_Search::get_qj_loading_style();
}
/** 获取内容最大宽度 */
public static function container_max_width(): int {
return AKSRT_Settings_Theme_Search::container_max_width();
}
/** 获取全局字体方案 */
public static function font_family(): string {
return AKSRT_Settings_Theme_Search::font_family();
}
/**
* 获取代码高亮配置
*
* @return array
*/
public static function get_code_highlight_config(): array {
return AKSRT_Settings_Theme_Search::get_code_highlight_config();
}
/**
* 获取系统公告配置
*
* @return array
*/
public static function get_system_notice_config(): array {
return AKSRT_Settings_Theme_Search::get_system_notice_config();
}
/**
* 获取侧边栏配置
*
* @return array
*/
public static function get_sidebar_config(): array {
return AKSRT_Settings_Theme_Search::get_sidebar_config();
}
/**
* 获取多语言翻译配置
*
* @return array
*/
public static function get_i18n_config(): array {
return AKSRT_Settings_Theme_Search::get_i18n_config();
}
/** 获取 ICP 备案号 */
public static function icp_filing(): string {
return trim((string) self::get_value('icp_filing', ''));
}
/** 获取公安备案号 */
public static function police_filing(): string {
return trim((string) self::get_value('police_number', ''));
}
/**
* 获取备案配置(统一 page-display footer schema 和全局设置)
* @return array {icp_enabled, icp_number, police_enabled, police_number}
*/
public static function get_filing_settings(): array {
$s = self::get_all();
$icp_enabled = !isset($s['footer_icp']) || !empty($s['footer_icp']);
$police_enabled = !isset($s['footer_police']) || !empty($s['footer_police']);
// 优先读 footer schema 的 icp_number,回退到全局 icp_filing
$icp_number = trim((string) ($s['icp_number'] ?? $s['icp_filing'] ?? ''));
$police_number = trim((string) ($s['police_number'] ?? ''));
return [
'icp_enabled' => $icp_enabled,
'icp_number' => $icp_number,
'police_enabled' => $police_enabled,
'police_number' => $police_number,
];
}
/** 获取页脚附加文字 */
public static function footer_text(): string {
return trim((string) self::get_value('footer_text', ''));
}
/**
* Header navigation display settings.
*
* @return array{fixed:bool,search_enabled:bool,user_menu:bool,publish_btn:bool,mobile_drawer:bool,nav_style:string,max_width:int,scroll_down_hide:bool,layout:string,mobile_layout:string,mobile_align:string}
*/
public static function get_header_nav_settings(): array {
$settings = self::get_all();
$nav_style = sanitize_key((string) ($settings['header_nav_style'] ?? 'default'));
$max_width = (int) ($settings['header_max_width'] ?? 1200);
$layout = sanitize_key((string) ($settings['header_layout'] ?? '2'));
$ml = sanitize_key((string) ($settings['mobile_header_layout'] ?? 'center'));
$ma = sanitize_key((string) ($settings['mobile_navbar_align'] ?? 'left'));
if (!in_array($nav_style, ['default', 'transparent', 'blur'], true)) {
$nav_style = 'default';
}
if (!in_array($max_width, [0, 1080, 1200, 1320], true)) {
$max_width = 1200;
}
return [
'fixed' => !isset($settings['header_fixed']) || !empty($settings['header_fixed']),
'search_enabled' => !isset($settings['header_search_enabled']) || !empty($settings['header_search_enabled']),
'user_menu' => !isset($settings['header_user_menu']) || !empty($settings['header_user_menu']),
'publish_btn' => !isset($settings['header_publish_btn']) || !empty($settings['header_publish_btn']),
'mobile_drawer' => !isset($settings['header_mobile_drawer']) || !empty($settings['header_mobile_drawer']),
'nav_style' => $nav_style,
'max_width' => $max_width,
'scroll_down_hide'=> !empty($settings['header_scroll_down_hide']),
'layout' => in_array($layout, ['1', '2', '3'], true) ? $layout : '2',
'mobile_layout' => in_array($ml, ['center', 'left'], true) ? $ml : 'center',
'mobile_align' => in_array($ma, ['top', 'left', 'right'], true) ? $ma : 'left',
];
}
/**
* Header publish button configuration.
*
* @return array{enabled:bool,text:string,radius:int,class:string}
*/
public static function get_header_newposts_config(): array {
$s = self::get_all();
return [
'enabled' => !empty($s['header_newposts_enabled']),
'text' => trim((string) ($s['header_newposts_text'] ?? '<i class="fa fa-pencil"></i> 发布')),
'radius' => max(0, min(30, (int) ($s['header_newposts_radius'] ?? 20))),
'class' => sanitize_html_class((string) ($s['header_newposts_class'] ?? '')),
];
}
/**
* Header theme color configuration.
*
* @return array{custom:bool,bg_custom:string,bg:string,color_custom:string}
*/
public static function get_header_theme_config(): array {
$s = self::get_all();
return [
'custom' => !empty($s['header_theme_custom']),
'bg_custom' => sanitize_hex_color((string) ($s['header_theme_bg_custom'] ?? '')) ?: '',
'bg' => sanitize_hex_color((string) ($s['header_theme_bg'] ?? '')) ?: '',
'color_custom' => sanitize_hex_color((string) ($s['header_theme_color_custom'] ?? '')) ?: '',
];
}
/**
* Category archive display settings.
*
* @return array
*/
public static function get_category_page_settings(): array {
$settings = self::get_all();
$header_style = sanitize_key((string) ($settings['category_header_style'] ?? 'cover'));
$list_mode = sanitize_key((string) ($settings['category_list_mode'] ?? 'grid'));
$per_page = (int) ($settings['category_per_page'] ?? 12);
$orderby = sanitize_key((string) ($settings['category_orderby'] ?? 'modified'));
if (!in_array($header_style, ['cover', 'simple', 'none'], true)) {
$header_style = 'cover';
}
if (!in_array($list_mode, ['grid', 'list', 'compact'], true)) {
$list_mode = 'grid';
}
if (!in_array($orderby, ['modified', 'date', 'views', 'comments', 'likes'], true)) {
$orderby = 'modified';
}
return [
'header_style' => $header_style,
'cover_enabled' => !isset($settings['category_cover_enabled']) || !empty($settings['category_cover_enabled']),
'desc_enabled' => !isset($settings['category_desc_enabled']) || !empty($settings['category_desc_enabled']),
'default_cover' => esc_url_raw((string) ($settings['category_default_cover'] ?? '')),
'list_mode' => $list_mode,
'filter_bar' => !isset($settings['category_filter_bar']) || !empty($settings['category_filter_bar']),
'sidebar' => !isset($settings['category_sidebar']) || !empty($settings['category_sidebar']),
'per_page' => max(4, min(48, $per_page)),
'post_count' => !empty($settings['category_post_count']),
'orderby' => $orderby,
];
}
/**
* Tag archive display settings.
*
* @return array
*/
public static function get_tag_page_settings(): array {
$settings = self::get_all();
$header_style = sanitize_key((string) ($settings['tag_header_style'] ?? 'simple'));
$list_mode = sanitize_key((string) ($settings['tag_list_mode'] ?? 'grid'));
$per_page = (int) ($settings['tag_per_page'] ?? 12);
$orderby = sanitize_key((string) ($settings['tag_orderby'] ?? 'count'));
if (!in_array($header_style, ['cover', 'simple', 'none'], true)) {
$header_style = 'simple';
}
if (!in_array($list_mode, ['grid', 'list'], true)) {
$list_mode = 'grid';
}
if (!in_array($orderby, ['count', 'name', 'modified'], true)) {
$orderby = 'count';
}
return [
'header_style' => $header_style,
'default_cover' => esc_url_raw((string) ($settings['tag_default_cover'] ?? '')),
'list_mode' => $list_mode,
'sidebar' => !isset($settings['tag_sidebar']) || !empty($settings['tag_sidebar']),
'per_page' => max(4, min(48, $per_page)),
'post_count' => !empty($settings['tag_post_count']),
'orderby' => $orderby,
];
}
/**
* Public user-home display settings.
*
* @return array
*/
public static function get_user_home_settings(): array {
return AKSRT_Settings_User_Runtime::get_user_home_settings();
}
/**
* Private user-center display settings.
*
* @return array{tabs:string[],avatar_upload:bool,cover_upload:bool,social_links:bool}
*/
public static function get_user_center_settings(): array {
return AKSRT_Settings_User_Runtime::get_user_center_settings();
}
/**
* User identity, level, badge, and report governance settings.
*
* @return array{
* verify:array{enabled:bool,public_display:bool,badge_text:string,accept_email_verified:bool,require_manual_review:bool},
* level:array{enabled:bool,public_display:bool,source:string,label_prefix:string,thresholds:array<int,int>},
* badge:array{enabled:bool,public_display:bool,limit:int,dictionary:array<int,array{slug:string,label:string,tone:string}>},
* report:array{enabled:bool,public_entry:bool,public_notice:bool,ban_notice_text:string,categories:array<int,array{slug:string,label:string}>}
* }
*/
public static function get_user_identity_settings(): array {
return AKSRT_Settings_User_Runtime::get_user_identity_settings();
}
/**
* Misc page display settings (404, search, author).
*
* @return array
*/
public static function get_other_page_settings(): array {
$settings = self::get_all();
$message = trim((string) ($settings['page_404_message'] ?? ''));
$search_per_page = max(4, min(48, (int) ($settings['page_search_per_page'] ?? 12)));
$author_per_page = max(4, min(48, (int) ($settings['page_author_posts_per_page'] ?? 12)));
$header_style = sanitize_key((string) ($settings['page_header_style'] ?? '1'));
if (!in_array($header_style, ['', '1', '2', '3'], true)) {
$header_style = '1';
}
return [
'header_style' => $header_style,
'header_cover_img' => esc_url_raw((string) ($settings['page_header_cover_img'] ?? '')),
'page_404_message' => $message !== '' ? $message : __('页面未找到', 'aksrt'),
'page_404_search' => !isset($settings['page_404_search']) || !empty($settings['page_404_search']),
'page_404_popular' => !isset($settings['page_404_popular']) || !empty($settings['page_404_popular']),
'page_404_back' => !isset($settings['page_404_back']) || !empty($settings['page_404_back']),
'page_search_sidebar' => !isset($settings['page_search_sidebar']) || !empty($settings['page_search_sidebar']),
'page_search_per_page' => $search_per_page,
'page_author_cover' => !isset($settings['page_author_cover']) || !empty($settings['page_author_cover']),
'page_author_sidebar' => !isset($settings['page_author_sidebar']) || !empty($settings['page_author_sidebar']),
'page_author_posts_per_page' => $author_per_page,
];
}
/**
* Special/topic page display settings.
*
* @return array
*/
public static function get_special_page_settings(): array {
$s = self::get_all();
$layout = sanitize_key((string) ($s['special_layout'] ?? 'grid'));
$source_type = sanitize_key((string) ($s['special_source_type'] ?? 'category'));
$subpage_display = sanitize_key((string) ($s['special_subpage_display'] ?? 'cards'));
$pagination = sanitize_key((string) ($s['special_pagination'] ?? 'numeric'));
$orderby = sanitize_key((string) ($s['special_orderby'] ?? 'date'));
if (!in_array($layout, ['grid', 'list', 'masonry'], true)) {
$layout = 'grid';
}
if (!in_array($source_type, ['category', 'tag', 'custom'], true)) {
$source_type = 'category';
}
if (!in_array($subpage_display, ['cards', 'list', 'grid'], true)) {
$subpage_display = 'cards';
}
if (!in_array($pagination, ['numeric', 'load_more', 'infinite'], true)) {
$pagination = 'numeric';
}
if (!in_array($orderby, ['date', 'modified', 'views', 'comments'], true)) {
$orderby = 'date';
}
return [
'cover_enabled' => !empty($s['special_cover_enabled']),
'summary_enabled' => !empty($s['special_summary_enabled']),
'summary_length' => max(50, min(500, (int) ($s['special_summary_length'] ?? 200))),
'default_cover' => esc_url_raw((string) ($s['special_default_cover'] ?? '')),
'layout' => $layout,
'columns' => max(1, min(4, (int) ($s['special_columns'] ?? 2))),
'source_type' => $source_type,
'source_ids' => trim((string) ($s['special_source_ids'] ?? '')),
'subpage_display' => $subpage_display,
'subpage_count' => max(1, min(20, (int) ($s['special_subpage_count'] ?? 6))),
'sidebar' => !empty($s['special_sidebar']),
'pagination' => $pagination,
'per_page' => max(4, min(48, (int) ($s['special_per_page'] ?? 12))),
'post_count' => !empty($s['special_post_count']),
'orderby' => $orderby,
];
}
/**
* Post-list card style and meta display settings.
*
* @return array{card_style:string,render_mode:string,show_author:bool,show_date:bool,show_views:bool,show_category:bool,show_comments:bool,show_likes:bool,excerpt_length:int}
*/
public static function get_post_list_style_settings(): array {
return AKSRT_Settings_Post_Display::get_post_list_style_settings();
}
/**
* Post-list thumbnail policy settings.
*
* @return array{priority:string[],fallback:string,aspect_ratio:string,multi_enabled:bool,multi_count:int,lazy:bool}
*/
public static function get_post_thumb_settings(): array {
return AKSRT_Settings_Post_Display::get_post_thumb_settings();
}
/**
* Post-list filter toolbar settings.
*
* @return array{enabled:bool,categories:bool,tags:bool,sort:bool}
*/
public static function get_post_filter_settings(): array {
return AKSRT_Settings_Post_Display::get_post_filter_settings();
}
/**
* Get custom filter definitions for a specific category.
* Finds the matching cat_custom_filter binding, falls back to global custom_filter.
*
* @param int $cat_id Category term ID.
* @return array{dimensions: array, show_cat: bool, show_tag: bool, show_topics: bool, show_orderby: bool}
*/
public static function get_filter_config_for_category(int $cat_id): array {
return AKSRT_Settings_Post_Display::get_filter_config_for_category($cat_id);
}
/**
* Single post/page display settings.
*
* @return array{toc_enabled:bool,toc_depth:int,reading_progress:bool,lightbox:bool,related_enabled:bool,related_count:int,like_enabled:bool,favorite_enabled:bool,share_enabled:bool,copyright_enabled:bool,print_enabled:bool,pdf_export_enabled:bool,word_count_enabled:bool,reading_time_enabled:bool}
*/
public static function get_post_page_settings(): array {
$settings = self::get_all();
$related_type = sanitize_key((string) ($settings['post_related_type'] ?? 'category'));
if (!in_array($related_type, ['category', 'tag', 'random'], true)) {
$related_type = 'category';
}
$related_orderby = sanitize_key((string) ($settings['post_related_orderby'] ?? 'rand'));
if (!in_array($related_orderby, ['rand', 'relevance', 'date', 'views', 'modified'], true)) {
$related_orderby = 'rand';
}
return [
'toc_enabled' => !isset($settings['post_toc_enabled']) || !empty($settings['post_toc_enabled']),
'toc_depth' => max(1, min(6, (int) ($settings['post_toc_depth'] ?? 3))),
'reading_progress' => !isset($settings['post_reading_progress']) || !empty($settings['post_reading_progress']),
'breadcrumbs' => !isset($settings['breadcrumbs_single_s']) || !empty($settings['breadcrumbs_single_s']),
'breadcrumbs_home' => trim((string) ($settings['breadcrumbs_home_text'] ?? '')) ?: __('首页', 'aksrt'),
'prevnext' => !isset($settings['post_prevnext_s']) || !empty($settings['post_prevnext_s']),
'authordesc' => !isset($settings['post_authordesc_s']) || !empty($settings['post_authordesc_s']),
'hide_time' => !empty($settings['post_single_hide_time_s']),
'lightbox' => !isset($settings['post_lightbox']) || !empty($settings['post_lightbox']),
'related_enabled' => !isset($settings['post_related_enabled']) || !empty($settings['post_related_enabled']),
'related_count' => max(1, min(20, (int) ($settings['post_related_count'] ?? 6))),
'related_type' => $related_type,
'related_orderby' => $related_orderby,
'related_title' => sanitize_text_field((string) ($settings['post_related_title'] ?? '')),
'like_enabled' => !isset($settings['post_like_enabled']) || !empty($settings['post_like_enabled']),
'favorite_enabled' => !isset($settings['post_favorite_enabled']) || !empty($settings['post_favorite_enabled']),
'share_enabled' => !isset($settings['share_s']) || !empty($settings['share_s']) || !empty($settings['post_share_enabled']),
'rewards_enabled' => !empty($settings['post_rewards_s']) || !empty($settings['post_rewards_enabled']),
'rewards_text' => trim((string) ($settings['post_rewards_text'] ?? '')) ?: __('赞赏支持', 'aksrt'),
'rewards_image' => esc_url_raw((string) ($settings['post_rewards_img'] ?? '')),
'rewards_btn_text' => trim((string) ($settings['post_rewards_btn_text'] ?? '')) ?: __('赞赏', 'aksrt'),
'copyright_enabled' => !isset($settings['post_copyright_enabled']) || !empty($settings['post_copyright_enabled']),
'copyright_text' => trim((string) ($settings['post_copyright_text'] ?? '')),
'front_content' => trim((string) ($settings['post_front_content'] ?? '')),
'after_content' => trim((string) ($settings['post_after_content'] ?? '')),
'maxheight_enabled' => !empty($settings['post_maxheight_kg']),
'maxheight' => max(0, (int) ($settings['post_maxheight'] ?? 1000)),
'yiyan_header' => !empty($settings['post_yiyan_header']),
'yiyan_footer' => !empty($settings['post_yiyan_footer']),
'yiyan_box' => !empty($settings['post_yiyan_box']),
'default_views_min' => max(0, (int) ($settings['post_default_views_min'] ?? 20)),
'default_views_max' => max(1, (int) ($settings['post_default_views_max'] ?? 50)),
'default_likes_min' => max(0, (int) ($settings['post_default_likes_min'] ?? 5)),
'default_likes_max' => max(1, (int) ($settings['post_default_likes_max'] ?? 15)),
'print_enabled' => !isset($settings['feature_print']) || !empty($settings['feature_print']),
'pdf_export_enabled' => !empty($settings['feature_pdf_export']),
'word_count_enabled' => !isset($settings['feature_word_count']) || !empty($settings['feature_word_count']),
'reading_time_enabled' => !isset($settings['feature_reading_time']) || !empty($settings['feature_reading_time']),
'article_image_cover' => !isset($settings['post_article_image_cover']) || !empty($settings['post_article_image_cover']),
'article_image_cover_scale' => max(10, min(100, (int) ($settings['post_article_image_cover_scale'] ?? 35))),
'article_slide_cover' => !isset($settings['post_article_slide_cover']) || !empty($settings['post_article_slide_cover']),
'article_video_cover' => !isset($settings['post_article_video_cover']) || !empty($settings['post_article_video_cover']),
'article_video_cover_scale' => max(20, min(100, (int) ($settings['post_article_video_cover_scale'] ?? 56))),
'button_toptext' => trim((string) ($settings['post_button_toptext'] ?? '')) ?: __('喜欢就支持一下吧', 'aksrt'),
'lightbox_thumbs' => !isset($settings['post_lightbox_thumbs']) || !empty($settings['post_lightbox_thumbs']),
'lightbox_zoom' => !isset($settings['post_lightbox_zoom']) || !empty($settings['post_lightbox_zoom']),
'lightbox_full' => !isset($settings['post_lightbox_full']) || !empty($settings['post_lightbox_full']),
'lightbox_down' => !empty($settings['post_lightbox_down']),
'lightbox_play' => !empty($settings['post_lightbox_play']),
'mobile_nav_s' => !isset($settings['article_nav_mobile_nav_s']) || !empty($settings['article_nav_mobile_nav_s']),
];
}
/**
* Share and poster settings.
*
* @return array{wechat_enabled:bool,wechat_appid:string,wechat_app_secret:string,only_logo:bool,compatible_s:bool,poster_img:string,poster_logo:string,share_img:string,share_desc:string}
*/
public static function get_share_settings(): array {
$settings = self::get_all();
return [
'wechat_enabled' => !empty($settings['share_wechat_s']),
'wechat_appid' => sanitize_text_field((string) ($settings['share_wechat_appid'] ?? '')),
'wechat_app_secret' => sanitize_text_field((string) ($settings['share_wechat_app_secret'] ?? '')),
'only_logo' => !empty($settings['share_only_logo']),
'compatible_s' => !empty($settings['share_img_compatible_s']),
'poster_img' => esc_url_raw((string) ($settings['share_img_byimg'] ?? '')),
'poster_logo' => esc_url_raw((string) ($settings['share_logo'] ?? '')),
'share_img' => esc_url_raw((string) ($settings['share_img'] ?? '')),
'share_desc' => sanitize_textarea_field((string) ($settings['share_desc'] ?? '')) ?: __('扫一扫 立即查看', 'aksrt'),
];
}
/**
* Front submit settings.
*
* @return array{enabled:bool,btn_text:string,title_min:int,title_max:int}
*/
public static function get_submit_settings(): array {
return AKSRT_Settings_Post_Display::get_submit_settings();
}
/**
* Comment display and behavior settings.
*
* @return array{order:string,pagination_mode:string,nested_depth:int,require_login:bool,allow_reply:bool,avatar_size:int,empty_text:string}
*/
public static function get_comment_display_settings(): array {
return AKSRT_Settings_Post_Display::get_comment_display_settings();
}
public static function get_withdrawal_settings(): array {
return AKSRT_Settings_Payment_Runtime::get_withdrawal_settings();
}
/**
* pre_get_posts: apply post_list_per_page on archive/tag/category/search/home pages.
*
* Overrides WP Settings > Reading "posts per page" for list views.
*/
public static function apply_list_per_page($query): void {
AKSRT_Settings_Post_Display::apply_list_per_page($query);
}
/** 获取Banner列表 */
public static function get_banners(string $position = ''): array {
return AKSRT_Settings_Display_Runtime::get_banners($position);
}
/** 保存Banner */
public static function save_banner(array $data): int {
return AKSRT_Settings_Display_Runtime::save_banner($data);
}
/** 删除Banner */
public static function delete_banner(string $id): void {
AKSRT_Settings_Display_Runtime::delete_banner($id);
}
/** 获取友链列表 */
public static function get_friend_links(): array {
return AKSRT_Settings_Display_Runtime::get_friend_links();
}
/** 保存友链 */
public static function save_friend_links(array $links): void {
AKSRT_Settings_Display_Runtime::save_friend_links($links);
}
/** 获取SMTP配置 */
public static function get_smtp(): array {
return get_option('aksrt_mail_smtp', [
'enabled' => false,
'host' => '',
'port' => 465,
'username' => '',
'password' => '',
'encryption' => 'ssl',
'from_name' => '',
'from_address' => '',
]);
}
/** 获取邮件品牌设置(发件人昵称/标题前缀/底部内容) */
public static function get_mail_branding(): array {
$s = self::get_all();
return [
'showname' => trim((string) ($s['mail_showname'] ?? '')),
'title_prefix' => trim((string) ($s['mail_title_prefix'] ?? '')),
'description' => trim((string) ($s['mail_description'] ?? '')),
'more_content' => trim((string) ($s['mail_more_content'] ?? '')),
];
}
/** 私信邮件接收组限制 (all/vip/vip2/admin) */
public static function get_email_private_receive_limit(): string {
return AKSRT_Settings_Integration::get_email_private_receive_limit();
}
/** 获取OAuth配置 */
public static function get_oauth(): array {
return AKSRT_Settings_Integration::get_oauth();
}
/** 检查OAuth平台是否已配置 */
public static function oauth_configured(string $provider): bool {
return AKSRT_Settings_Integration::oauth_configured($provider);
}
// ============================================
// OAuth 代理登录 & 自动创建用户
// ============================================
/** OAuth 代理登录模式: 'off' | 'server' | 'client' (schema 存 'close'→映射为 'off') */
public static function oauth_proxy_mode(): string {
return AKSRT_Settings_Integration::oauth_proxy_mode();
}
/** OAuth 代理登录 HMAC 密钥 */
public static function oauth_proxy_secret(): string {
return AKSRT_Settings_Integration::oauth_proxy_secret();
}
/** OAuth 代理登录服务端地址(客户端模式使用) */
public static function oauth_proxy_server_url(): string {
return AKSRT_Settings_Integration::oauth_proxy_server_url();
}
/** OAuth 代理登录允许的平台列表(服务端模式使用) */
public static function oauth_proxy_allowed_providers(): array {
return AKSRT_Settings_Integration::oauth_proxy_allowed_providers();
}
/** OAuth 代理登录启用的平台列表(客户端模式使用) */
public static function oauth_proxy_client_providers(): array {
return AKSRT_Settings_Integration::oauth_proxy_client_providers();
}
/**
* 获取微信公众号登录完整配置
*
* @return array{gzh_type:string,token:string,token_nocheck:bool,encoding_aes_key:string,appid:string,appsecret:string,code_qrcode:string,code_keyword:string,code_reply:string,code_subscribe_reply:string,subscribe_msg:string,new_subscribe_msg:string,scan_msg:string,auto_reply_text:string,auto_reply_search:string,auto_reply_image:string,auto_reply_voice:string,auto_reply_default:string,gzh_menu:string,priority:bool,auto:bool,auto_expires:int}
*/
public static function get_weixingzh_settings(): array {
return AKSRT_Settings_Integration::get_weixingzh_settings();
}
/**
* 获取 OAuth 代理登录完整配置(aksrt_settings 优先,BC fallback aksrt_oauth)
*
* @return array{mode:string,secret:string,server_url:string,server_providers:array,client_providers:array,gzh_type:string}
*/
public static function get_oauth_proxy_settings(): array {
return AKSRT_Settings_Integration::get_oauth_proxy_settings();
}
// ============================================
// 底部信息配置
// ============================================
/**
* 获取底部信息完整配置(统一 aksrt_footer_settings + aksrt_settings page-display footer 字段)
* @return array
*/
public static function get_footer_settings(): array {
return AKSRT_Settings_Home_Cms::get_footer_settings();
}
/** 获取联系图标列表(仅返回启用的) */
public static function get_footer_contacts(): array {
return AKSRT_Settings_Home_Cms::get_footer_contacts();
}
/** 获取快速链接列表(仅返回启用的,按排序) */
public static function get_quick_links(): array {
return AKSRT_Settings_Home_Cms::get_quick_links();
}
/** 获取更多链接列表(仅返回启用的,按排序) */
public static function get_more_links(): array {
return AKSRT_Settings_Home_Cms::get_more_links();
}
/** 获取热门分类显示数量 */
public static function get_hot_categories_count(): int {
return AKSRT_Settings_Home_Cms::get_hot_categories_count();
}
/** 获取版权文字 */
public static function get_copyright_text(): string {
return AKSRT_Settings_Home_Cms::get_copyright_text();
}
/**
* 获取页脚品牌列(第一列)配置
* @return array {m_s, img, img_dark, title, custom_code}
*/
public static function get_footer_brand_settings(): array {
return AKSRT_Settings_Home_Cms::get_footer_brand_settings();
}
/**
* 获取页脚扩展联系方式配置
* @return array {m_s, wechat_img, qq, weibo, email, more, code_1, code_2}
*/
public static function get_footer_contact_extended_settings(): array {
return AKSRT_Settings_Home_Cms::get_footer_contact_extended_settings();
}
/**
* 获取页脚二维码图片组(第三列)
* @return array {m_s, items: [{text, img}]}
*/
public static function get_footer_mini_img_settings(): array {
return AKSRT_Settings_Home_Cms::get_footer_mini_img_settings();
}
/**
* 获取页脚底部自定义代码
*/
public static function get_footer_customize_code(): string {
return AKSRT_Settings_Home_Cms::get_footer_customize_code();
}
/** 获取审核配置 */
public static function get_moderation(): array {
return AKSRT_Settings_Extension_Runtime::get_moderation();
}
// ============================================
// 文章布局配置
// ============================================
/**
* 获取归档布局模式。
*
* 从 post_list.list schema 的 render_mode 字段读取。
* 后台可在 /post-list/list 页面配置。
*
* @return string grid-cms|list|compact
*/
public static function get_archive_layout(): string {
return AKSRT_Settings_Post_Display::get_archive_layout();
}
/**
* 获取文章列表分页模式
* @return string numbered|load_more|infinite
*/
public static function get_post_pagination_mode(): string {
return AKSRT_Settings_Post_Display::get_post_pagination_mode();
}
/**
* 获取评论列表分页模式
* @return string numbered|load_more|infinite
*/
public static function get_comment_pagination_mode(): string {
return AKSRT_Settings_Post_Display::get_comment_pagination_mode();
}
/**
* 获取懒加载配置
*
* 返回 schema 定义的全部字段:全局开关、动画、占位图、模糊预览、
* 以及 8 项粒度范围开关。
*
* @return array {enabled, animation, placeholder_url, blur, avatar, content, comment, private, slider, cover, other, widget}
*/
public static function get_lazyload_config(): array {
$s = self::get_all();
// placeholder 兼容:schema 存 lazyload_placeholder,REST/Vue 存 lazyload_placeholder_url
$placeholder = '';
if (!empty($s['lazyload_placeholder'])) {
$placeholder = $s['lazyload_placeholder'];
} elseif (!empty($s['lazyload_placeholder_url'])) {
$placeholder = $s['lazyload_placeholder_url'];
}
return [
'enabled' => !isset($s['lazyload_enabled']) || !empty($s['lazyload_enabled']),
'animation' => $s['lazyload_animation'] ?? 'blur',
'placeholder_url' => (string) $placeholder,
'blur' => !isset($s['lazyload_blur']) || !empty($s['lazyload_blur']),
'avatar' => !isset($s['lazyload_avatar']) || !empty($s['lazyload_avatar']),
'content' => !empty($s['lazyload_content']),
'comment' => !isset($s['lazyload_comment']) || !empty($s['lazyload_comment']),
'private' => !isset($s['lazyload_private']) || !empty($s['lazyload_private']),
'slider' => !isset($s['lazyload_slider']) || !empty($s['lazyload_slider']),
'cover' => !isset($s['lazyload_cover']) || !empty($s['lazyload_cover']),
'other' => !isset($s['lazyload_other']) || !empty($s['lazyload_other']),
'widget' => !isset($s['lazyload_widget']) || !empty($s['lazyload_widget']),
];
}
// ============================================
// CMS 配置
// ============================================
/**
* 获取站点全局风格。
*
* v4 起主题统一为 CMS / 资源站形态,恒返回 'cms'。
* 保留方法签名以兼容旧调用。
*
* @return string 始终为 'cms'
*/
public static function get_site_profile(): string {
return AKSRT_Settings_Home_Cms::get_site_profile();
}
/**
* CMS 功能开关(合并默认值)。
* @return array
*/
public static function get_cms_features(): array {
return AKSRT_Settings_Home_Cms::get_cms_features();
}
/**
* 单项 CMS 功能开关读取。
*/
public static function cms_feature(string $key, $default = null) {
return AKSRT_Settings_Home_Cms::cms_feature($key, $default);
}
/** 所有邮件事件类型常量 */
public const EMAIL_EVENTS = AKSRT_Settings_Mail::EMAIL_EVENTS;
}
return AKSRT_Settings::get_instance();