!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']), // Unified with header_newposts_enabled (zibll nav_newposts). 'publish_btn' => !isset($settings['header_newposts_enabled']) || !empty($settings['header_newposts_enabled']), 'mobile_drawer' => !isset($settings['header_mobile_drawer']) || !empty($settings['header_mobile_drawer']), 'nav_style' => $nav_style, 'max_width' => $max_width, // Zibll default: true when fixed. 'scroll_down_hide' => !isset($settings['header_scroll_down_hide']) || !empty($settings['header_scroll_down_hide']), 'layout' => in_array($layout, ['1', '2', '3'], true) ? $layout : '1', 'mobile_layout' => in_array($ml, ['center', 'left'], true) ? $ml : 'center', 'mobile_align' => in_array($ma, ['top', 'left', 'right'], true) ? $ma : 'left', 'nav_pay_vip' => !isset($settings['header_nav_pay_vip']) || !empty($settings['header_nav_pay_vip']), 'nav_user_pay_vip' => !isset($settings['header_nav_user_pay_vip']) || !empty($settings['header_nav_user_pay_vip']), ]; } /** * Header publish button configuration. * * @return array{enabled:bool,text:string,radius:int,class:string,types:string[]} */ public static function get_header_newposts_config(): array { $s = self::get_all(); $types = []; if (!empty($s['header_newposts_types']) && is_array($s['header_newposts_types'])) { $types = array_values(array_filter(array_map('sanitize_key', $s['header_newposts_types']))); } // zibll nav_newposts_radius is bool pill; map true→20px, false→0. Legacy int still accepted once. $raw_radius = $s['header_newposts_radius'] ?? true; if (is_bool($raw_radius) || $raw_radius === '0' || $raw_radius === '1' || $raw_radius === 0 || $raw_radius === 1) { $radius_px = !empty($raw_radius) ? 20 : 0; $radius_pill = !empty($raw_radius); } else { $radius_px = max(0, min(30, (int) $raw_radius)); $radius_pill = $radius_px >= 16; } return [ // Default on like zibll nav_newposts when key unset. 'enabled' => !isset($s['header_newposts_enabled']) || !empty($s['header_newposts_enabled']), 'text' => trim((string) ($s['header_newposts_text'] ?? ' 发布')), 'radius' => $radius_px, 'radius_pill' => $radius_pill, 'class' => sanitize_html_class((string) (($s['header_newposts_class'] ?? '') !== '' ? $s['header_newposts_class'] : 'jb-blue')), 'types' => $types, ]; } /** * 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, ]; } /** * 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, ]; } /** * 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'), ]; } /** * 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 { // Canonical assembly lives in the post-display helper (related style/source split, aliases). if (class_exists('AKSRT\\Settings\\PostDisplay')) { return PostDisplay::get_post_page_settings(); } $settings = self::get_all(); 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'), '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_style' => 'img', 'related_source' => 'category', 'related_type' => 'category', 'related_orderby' => 'views', 'related_title' => sanitize_text_field((string) ($settings['post_related_title'] ?? '相关推荐')), ]; } /** * 获取懒加载配置 * * 返回 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']), ]; } /** * 获取备案配置(统一 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', '')); } /** 获取 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', '')); } /** 获取导航 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'] ?? ''); } /** 获取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', '')); } /** 获取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'] ?? '')), ]; } }