feat(navigation): hard-switch to Zibll navigation and Font Awesome 5

This commit is contained in:
kate522 committed 2026-08-18 20:46:21 +08:00
1 parent 3c3ddac8be
commit a0b84977a2
630 files changed
+101647 -11293

No files matched your search

+107 -46
View File
@@ -49,45 +49,109 @@ trait DisplayPageGroups {
/**
* 获取顶部多功能组件设置
*/
public static function get_header_components_settings(): array {
$s = self::get_all();
$allowed_page_types = [
'home',
'category',
'tag',
'author',
'single',
'search',
'page',
];
$show_on = isset($s['header_components_show_on']) ? (array) $s['header_components_show_on'] : ['home'];
$show_on = array_values(array_intersect(
array_map('sanitize_key', $show_on),
$allowed_page_types
));
$show_type = $s['header_components_device_visibility'] ?? '';
if (!in_array($show_type, ['', 'only_pc', 'only_sm'], true)) {
$show_type = '';
}
return [
'search_enabled' => self::header_components_search_enabled(),
'search_config' => self::get_header_components_search_config(),
'cards_enabled' => self::header_components_cards_enabled(),
'show_on_pages' => $show_on,
'show_type' => $show_type,
'filter_blur' => isset($s['header_components_filter_blur_devices']) ? array_values(array_intersect(array_map('sanitize_key', (array) $s['header_components_filter_blur_devices']), ['pc', 'mobile'])) : [],
'card_show' => isset($s['header_components_card_show_devices']) ? array_values(array_intersect(array_map('sanitize_key', (array) $s['header_components_card_show_devices']), ['pc', 'mobile'])) : ['pc', 'mobile'],
'slider_config' => self::get_slider_config(),
'icon_cards' => self::get_header_components_icon_cards(),
'card_columns' => self::get_header_components_card_columns(),
'card_bg_enabled' => self::header_components_card_bg_enabled(),
];
}
public static function get_header_slider_settings(): array {
$s = self::get_all();
$allowed_page_types = [
'home',
'category',
'tag',
'author',
'single',
'search',
'page',
'topics',
'forum_home',
'forum_plate',
'forum_post',
];
$show_on = isset($s['header_slider_show']) ? (array) $s['header_slider_show'] : [];
$show_on = array_values(array_intersect(
array_map('sanitize_key', $show_on),
$allowed_page_types
));
$show_type = $s['header_slider_show_type'] ?? '';
if (!in_array($show_type, ['', 'only_pc', 'only_sm'], true)) {
$show_type = '';
}
$slider_option = is_array($s['header_slider_option'] ?? null) ? $s['header_slider_option'] : self::header_slider_option_defaults();
$search_option = is_array($s['header_slider_search_option'] ?? null) ? $s['header_slider_search_option'] : self::header_slider_search_defaults();
$card_option = is_array($s['header_slider_card_option'] ?? null) ? $s['header_slider_card_option'] : self::header_slider_card_defaults();
return [
'slides' => is_array($s['header_slider'] ?? null) ? $s['header_slider'] : self::header_slider_default_slides(),
'show_on_pages' => $show_on,
'show_type' => $show_type,
'nav_color' => sanitize_hex_color((string) ($s['header_slider_nav_color'] ?? '')) ?: '',
'slider_config' => $slider_option,
'search_show' => self::sanitize_device_visibility($s['header_slider_search_s'] ?? ['pc_s', 'm_s']),
'search_config' => $search_option,
'card_show' => self::sanitize_device_visibility($s['header_slider_card_s'] ?? ['pc_s', 'm_s']),
'card_config' => $card_option,
'filter_blur' => self::sanitize_device_visibility($s['header_slider_filter_blur'] ?? ['pc_s', 'm_s']),
];
}
/** @return list<array<string,mixed>> */
private static function header_slider_default_slides(): array {
$base = defined('AKSRT_URI') ? trailingslashit(AKSRT_URI) . 'assets/vendor/zibll/img/' : '';
$slides = [];
foreach (['slider-bg.jpg', 'user_t.jpg'] as $image) {
$slides[] = [
'background' => $base . $image,
'link' => ['url' => 'https://www.zibll.com/', 'target' => '_blank'],
'text' => ['desc' => '', 'title' => ''],
'text_align' => 'left-bottom',
'text_parallax' => 30,
'text_size_m' => 20,
'text_size_pc' => 30,
];
}
return $slides;
}
/** @return array<string,mixed> */
private static function header_slider_option_defaults(): array {
return [
'direction' => 'horizontal', 'loop' => true, 'button' => true,
'pagination' => true, 'effect' => 'slide', 'scale_height' => false,
'auto_height' => false, 'pc_height' => 550, 'm_height' => 280,
'spacebetween' => 0, 'speed' => 0, 'autoplay' => true, 'interval' => 6,
];
}
/** @return array<string,mixed> */
private static function header_slider_search_defaults(): array {
return [
'show_keywords' => true, 'popular_limit' => 6, 'show_input_cat' => false,
'in_cat' => '', 'more_cats' => [], 'show_type' => false, 'in_type' => 'post',
'before_html' => '<div class="em16 font-bold mb10">更优雅的Wordpress主题</div><div>这是导航栏幻灯片多功能组件,可在后台进行配置</div>',
'after_html' => '',
];
}
/** @return array<string,mixed> */
private static function header_slider_card_defaults(): array {
return [
'show_widget_bg' => false,
'icon_radius4' => false,
'cards' => [
['icon' => 'zibsvg-vip_1', 'customize_icon' => '', 'icon_class' => 'c-yellow', 'link' => [], 'title' => '图标卡片', 'desc' => '这是一个图标卡片示例'],
['icon' => 'zibsvg-vip_2', 'customize_icon' => '', 'icon_class' => 'c-blue-2', 'link' => [], 'title' => '原创作品', 'desc' => '这是一个图标卡片示例'],
['icon' => 'zibsvg-hot', 'customize_icon' => '', 'icon_class' => 'jb-pink', 'link' => [], 'title' => '灵感来源<badge class="ml6 jb-yellow">NEW</badge>', 'desc' => '这是一个图标卡片示例'],
['icon' => 'fa fas fa-ioxhost', 'customize_icon' => '', 'icon_class' => 'jb-cyan', 'link' => [], 'title' => '系统工具 <badge class="ml6 jb-blue">GO <span class="fa fas fa-angle-right em12"></span></badge>', 'desc' => '这是一个图标卡片示例'],
],
];
}
/** @return list<string> */
private static function sanitize_device_visibility($value): array {
return array_values(array_intersect(array_map('sanitize_key', (array) $value), ['pc_s', 'm_s']));
}
/**
* 获取"全局&功能"域的合并设置
*/
public static function get_global_settings(): array {
$s = self::get_all();
return [
'site_logo' => self::logo_url(),
'site_logo_dark' => self::logo_dark_url(),
@@ -105,12 +169,14 @@ trait DisplayPageGroups {
'qj_dh_xs' => self::get_qj_loading_style(),
'container_max_width' => self::container_max_width(),
'font_family' => self::font_family(),
'search_type' => self::search_mode(),
'search_placeholder' => self::search_placeholder(),
'search_history_enabled' => self::search_history_enabled(),
'hot_search_enabled' => self::hot_search_enabled(),
'hot_search_keywords' => self::hot_search_keywords(),
'search_suggestions_enabled' => self::search_suggestions_enabled(),
'search_type' => !isset($s['search_type']) || !empty($s['search_type']),
'search_type_in' => sanitize_key((string) ($s['search_type_in'] ?? 'post')),
'search_placeholder' => self::search_placeholder(),
'search_history' => self::search_history_enabled(),
'search_popular_key' => self::hot_search_enabled(),
'search_popular_title' => self::search_popular_title(),
'search_popular_sticky' => self::search_popular_sticky(),
'search_popular_key_num' => max(10, min(50, (int) ($s['search_popular_key_num'] ?? 20))),
'search_posts' => self::search_posts_enabled(),
'search_no_page' => self::search_no_page(),
'search_exclude_cats' => self::search_exclude_cats(),
@@ -132,8 +198,6 @@ trait DisplayPageGroups {
'footer' => self::get_footer_settings(),
'tabbar' => self::get_footer_tabbar_settings(),
'floating_buttons' => self::get_floating_buttons_settings(),
'header_nav' => self::get_header_nav_settings(),
'header_newposts' => self::get_header_newposts_config(),
'header_theme' => self::get_header_theme_config(),
'friend_links' => self::get_friend_links(),
'cms_features' => self::get_cms_features(),
@@ -147,7 +211,7 @@ trait DisplayPageGroups {
*/
public static function get_page_display_settings(): array {
return [
'header_components' => self::get_header_components_settings(),
'header_slider' => self::get_header_slider_settings(),
'homepage' => self::get_homepage_fixed_settings(),
'category_recommend' => self::get_category_recommend_settings(),
'category' => self::get_category_page_settings(),
@@ -155,9 +219,6 @@ trait DisplayPageGroups {
'user_home' => self::get_user_home_settings(),
'other' => self::get_other_page_settings(),
'background' => self::get_global_background_settings(),
'menu_decoration' => function_exists('aksrt_get_menu_decoration_settings')
? aksrt_get_menu_decoration_settings()
: [],
];
}
+12 -159
View File
@@ -56,135 +56,6 @@ class DisplayRuntime {
update_option('aksrt_friend_links', $links);
}
/**
* 是否显示顶部组件搜索覆盖框
*/
public static function header_components_search_enabled(): bool {
$settings = Settings::get_all();
return !empty($settings['header_components_search_enabled']);
}
/**
* Hero 搜索组件详细配置(PC/移动分别 + 子选项)
*
* @return array{pc:bool,mobile:bool,show:bool,show_keywords:bool,popular_limit:int,show_input_cat:bool,show_type:bool,keywords:string[],categories:array,type_options:array,before_html:string,after_html:string}
*/
public static function get_header_components_search_config(): array {
$settings = Settings::get_all();
$master = self::header_components_search_enabled();
$is_mobile = function_exists('wp_is_mobile') && wp_is_mobile();
$pc_on = $master && (!isset($settings['header_components_search_pc']) || !empty($settings['header_components_search_pc']));
$mobile_on = $master && (!isset($settings['header_components_search_mobile']) || !empty($settings['header_components_search_mobile']));
$show = $is_mobile ? $mobile_on : $pc_on;
$show_kw = !empty($settings['header_components_search_show_keywords']);
$kw_limit = max(1, min(50, (int) ($settings['header_components_search_popular_limit'] ?? 6)));
$show_cat = !empty($settings['header_components_search_show_input_cat']);
$show_type = !empty($settings['header_components_search_show_type']);
$in_cat = sanitize_text_field((string) ($settings['header_components_search_in_cat'] ?? ''));
$in_type = sanitize_key((string) ($settings['header_components_search_in_type'] ?? 'post')) ?: 'post';
$more_cats = isset($settings['header_components_search_more_cats'])
? array_values(array_filter(array_map('absint', (array) $settings['header_components_search_more_cats'])))
: [];
// Mobile: hide hot keywords (zibll).
if ($is_mobile) {
$show_kw = false;
}
$keywords = [];
if ($show && $show_kw) {
if (function_exists('aksrt_get_search_hot_keywords')) {
$keywords = (array) aksrt_get_search_hot_keywords();
} else {
$raw = $settings['hot_search_keywords'] ?? '';
$keywords = is_array($raw) ? $raw : preg_split('/[\s,]+/', (string) $raw, -1, PREG_SPLIT_NO_EMPTY);
}
$keywords = array_slice(array_map('sanitize_text_field', array_values($keywords)), 0, $kw_limit);
}
$categories = [];
if ($show && $show_cat) {
$cat_args = ['hide_empty' => true, 'number' => 50];
if ($more_cats) {
$cat_args['include'] = $more_cats;
$cat_args['orderby'] = 'include';
$cat_args['hide_empty'] = false;
}
$cats = get_categories($cat_args);
foreach ($cats as $cat) {
$categories[] = ['id' => (int) $cat->term_id, 'name' => (string) $cat->name];
}
}
$type_options = [];
if ($show && $show_type) {
$types = Settings::get_search_content_types();
$labels = [
'post' => __('文章', 'aksrt'),
'user' => __('用户', 'aksrt'),
'page' => __('页面', 'aksrt'),
];
$enabled = $types['enabled'] ?? $types;
if (is_array($enabled)) {
foreach ($enabled as $type_key => $type_value) {
// Support both map[key=>bool] and list of keys.
if (is_int($type_key) && is_string($type_value)) {
$k = $type_value;
$on = true;
} else {
$k = (string) $type_key;
$on = (bool) $type_value;
}
if (!$on || $k === '') {
continue;
}
$type_options[] = [
'key' => $k,
'label' => $labels[$k] ?? $k,
];
}
}
}
$before_html = isset($settings['header_components_search_before_html'])
? (string) $settings['header_components_search_before_html']
: '';
$after_html = isset($settings['header_components_search_after_html'])
? (string) $settings['header_components_search_after_html']
: '';
return [
'pc' => $pc_on,
'mobile' => $mobile_on,
'show' => $show,
'show_keywords' => $show_kw,
'popular_limit' => $kw_limit,
'show_input_cat' => $show_cat,
'show_type' => $show_type,
'in_cat' => $in_cat,
'in_type' => $in_type,
'more_cats' => $more_cats,
'keywords' => $keywords,
'categories' => $categories,
'type_options' => $type_options,
'before_html' => $before_html,
'after_html' => $after_html,
];
}
public static function header_components_cards_enabled(): bool {
$settings = Settings::get_all();
return !empty($settings['header_components_cards_enabled']);
}
public static function homepage_module_hero_enabled(): bool {
$settings = Settings::get_all();
return !isset($settings['homepage_module_hero_enabled']) || !empty($settings['homepage_module_hero_enabled']);
}
public static function homepage_module_banner_enabled(): bool {
$settings = Settings::get_all();
return !isset($settings['homepage_module_banner_enabled']) || !empty($settings['homepage_module_banner_enabled']);
@@ -197,47 +68,29 @@ class DisplayRuntime {
*/
public static function get_slider_config(): array {
$settings = Settings::get_all();
$config = $settings['slider_config'] ?? [];
$config = is_array($settings['header_slider_option'] ?? null) ? $settings['header_slider_option'] : [];
return [
'effect' => in_array($config['effect'] ?? '', ['fade', 'slide', 'cube', 'coverflow', 'flip'], true) ? $config['effect'] : 'fade',
'direction' => in_array($settings['slider_config_direction'] ?? ($config['direction'] ?? ''), ['horizontal', 'vertical'], true)
? ($settings['slider_config_direction'] ?? ($config['direction'] ?? 'horizontal')) : 'horizontal',
'direction' => in_array($config['direction'] ?? '', ['horizontal', 'vertical'], true) ? $config['direction'] : 'horizontal',
'loop' => !isset($config['loop']) || !empty($config['loop']),
'autoplay_interval' => max(1000, min(30000, (int) ($config['autoplay_interval'] ?? 5000))),
'autoplay_interval' => max(0, min(20000, (int) ($config['interval'] ?? 6) * 1000)),
'pagination' => !isset($config['pagination']) || !empty($config['pagination']),
'navigation' => !isset($config['navigation']) || !empty($config['navigation']),
'button' => isset($settings['slider_config_button']) ? !empty($settings['slider_config_button']) : (!isset($config['button']) || !empty($config['button'])),
'button' => !isset($config['button']) || !empty($config['button']),
'auto_height' => !empty($config['auto_height']),
'pc_height' => isset($config['pc_height']) && $config['pc_height'] !== '' ? sanitize_text_field($config['pc_height']) : '',
'mobile_height' => isset($config['mobile_height']) && $config['mobile_height'] !== '' ? sanitize_text_field($config['mobile_height']) : '',
'max_height' => isset($settings['slider_config_max_height']) && $settings['slider_config_max_height'] !== '' ? sanitize_text_field($settings['slider_config_max_height']) : (isset($config['max_height']) && $config['max_height'] !== '' ? sanitize_text_field($config['max_height']) : ''),
'min_height' => isset($settings['slider_config_min_height']) && $settings['slider_config_min_height'] !== '' ? sanitize_text_field($settings['slider_config_min_height']) : (isset($config['min_height']) && $config['min_height'] !== '' ? sanitize_text_field($config['min_height']) : ''),
'scale_height' => !empty($settings['slider_config_scale_height'] ?? ($config['scale_height'] ?? false)),
'scale' => !empty($settings['slider_config_scale'] ?? ($config['scale'] ?? false)),
'speed' => max(100, min(3000, (int) ($settings['slider_config_speed'] ?? ($config['speed'] ?? 300)))),
'space_between' => max(0, min(100, (int) ($config['space_between'] ?? 0))),
'nav_color' => sanitize_hex_color((string) ($settings['header_components_nav_color'] ?? '')) ?: '',
'mobile_height' => isset($config['m_height']) && $config['m_height'] !== '' ? sanitize_text_field($config['m_height']) : '',
'max_height' => isset($config['max_height']) && $config['max_height'] !== '' ? sanitize_text_field($config['max_height']) : '',
'min_height' => isset($config['min_height']) && $config['min_height'] !== '' ? sanitize_text_field($config['min_height']) : '',
'scale_height' => !empty($config['scale_height']),
'scale' => (int) ($config['scale'] ?? 40),
'speed' => max(0, min(3000, (int) ($config['speed'] ?? 0))),
'space_between' => max(0, min(500, (int) ($config['spacebetween'] ?? 0))),
'nav_color' => sanitize_hex_color((string) ($settings['header_slider_nav_color'] ?? '')) ?: '',
];
}
public static function get_header_components_icon_cards(): array {
$settings = Settings::get_all();
$cards = $settings['header_components_icon_cards'] ?? [];
return is_array($cards) ? array_values($cards) : [];
}
public static function get_header_components_card_columns(): int {
$settings = Settings::get_all();
$columns = (int) ($settings['header_components_card_columns'] ?? 4);
return max(2, min(6, $columns));
}
public static function header_components_card_bg_enabled(): bool {
$settings = Settings::get_all();
return !empty($settings['header_components_card_bg']);
}
/**
* 获取全局背景设置
*/
+4 -89
View File
@@ -8,91 +8,6 @@ namespace AKSRT\Settings;
defined('ABSPATH') || exit;
trait FacadeBulk {
/**
* 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,nav_pay_vip:bool,nav_user_pay_vip:bool
* }
*/
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'] ?? '1'));
$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']),
// 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_intersect(array_map('sanitize_key', $s['header_newposts_types']), ['post']));
}
// 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'] ?? '<i class="fa fa-pencil"></i> 发布')),
'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.
*
@@ -102,10 +17,10 @@ trait FacadeBulk {
$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'] ?? '')) ?: '',
'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'] ?? '')) ?: '',
];
}
-1
View File
@@ -218,7 +218,6 @@ class HomeCms {
'home_list_sort_dropdown' => !empty($s['home_list_sort_dropdown']),
'homepage_tab_posts_per_page' => max(1, min(20, (int) ($s['homepage_tab_posts_per_page'] ?? 6))),
'homepage_tab_limit' => max(1, min(12, (int) ($s['homepage_tab_limit'] ?? 4))),
'homepage_module_hero_enabled' => !isset($s['homepage_module_hero_enabled']) || !empty($s['homepage_module_hero_enabled']),
'homepage_module_banner_enabled' => !isset($s['homepage_module_banner_enabled']) || !empty($s['homepage_module_banner_enabled']),
];
-49
View File
@@ -151,41 +151,10 @@ trait HomepageReader {
return HomeCms::homepage_tab_limit();
}
// ============================================
// 顶部多功能组件设置(图标卡片 + 搜索覆盖)
// ============================================
/**
* 是否显示顶部组件搜索覆盖框
*/
public static function header_components_search_enabled(): bool {
return DisplayRuntime::header_components_search_enabled();
}
/**
* 顶部组件搜索详细配置(PC/移动分别 + 子选项)
*
* @return array{pc:bool,mobile:bool,show_keywords:bool,popular_limit:int,show_input_cat:bool,show_type:bool,keywords:string[],categories:array,type_options:array}
*/
public static function get_header_components_search_config(): array {
return DisplayRuntime::get_header_components_search_config();
}
/**
* 是否显示顶部组件图标卡片覆盖
*/
public static function header_components_cards_enabled(): bool {
return DisplayRuntime::header_components_cards_enabled();
}
/**
* 获取顶部组件图标卡片配置
* @return array
*/
public static function homepage_module_hero_enabled(): bool {
return DisplayRuntime::homepage_module_hero_enabled();
}
public static function homepage_module_banner_enabled(): bool {
return DisplayRuntime::homepage_module_banner_enabled();
}
@@ -199,24 +168,6 @@ trait HomepageReader {
return DisplayRuntime::get_slider_config();
}
public static function get_header_components_icon_cards(): array {
return DisplayRuntime::get_header_components_icon_cards();
}
/**
* 获取顶部组件卡片列数
*/
public static function get_header_components_card_columns(): int {
return DisplayRuntime::get_header_components_card_columns();
}
/**
* 是否显示顶部组件卡片背景色
*/
public static function header_components_card_bg_enabled(): bool {
return DisplayRuntime::header_components_card_bg_enabled();
}
/**
* 获取页脚配色配置
*/
+7 -7
View File
@@ -196,7 +196,7 @@ class Integration {
[
'id' => 'tab_home',
'type' => 'home',
'icon' => 'fas fa-home',
'icon' => 'fa fas fa-home',
'text' => __('首页', 'aksrt'),
'link' => '',
'badge' => '',
@@ -210,7 +210,7 @@ class Integration {
[
'id' => 'tab_category',
'type' => 'category',
'icon' => 'fas fa-th-large',
'icon' => 'fa fas fa-th-large',
'text' => __('分类', 'aksrt'),
'link' => '',
'badge' => '',
@@ -223,7 +223,7 @@ class Integration {
[
'id' => 'tab_search',
'type' => 'search',
'icon' => 'fas fa-search',
'icon' => 'fa fas fa-search',
'text' => __('搜索', 'aksrt'),
'link' => '',
'badge' => '',
@@ -237,7 +237,7 @@ class Integration {
[
'id' => 'tab_auth',
'type' => 'auth',
'icon' => 'fas fa-user',
'icon' => 'fa fas fa-user',
'text' => __('我的', 'aksrt'),
'link' => '',
'badge' => '',
@@ -439,7 +439,7 @@ class Integration {
[
'id' => 'btn_wechat',
'type' => 'service_wechat',
'icon' => 'fab fa-weixin',
'icon' => 'fa fab fa-weixin',
'icon_dark' => '',
'icon_light' => '',
'text' => __('微信', 'aksrt'),
@@ -463,7 +463,7 @@ class Integration {
[
'id' => 'btn_theme',
'type' => 'theme_mode',
'icon' => 'fas fa-sun',
'icon' => 'fa fas fa-sun',
'icon_dark' => '',
'icon_light' => '',
'text' => __('主题', 'aksrt'),
@@ -487,7 +487,7 @@ class Integration {
[
'id' => 'btn_top',
'type' => 'back_top',
'icon' => 'fas fa-chevron-up',
'icon' => 'fa fas fa-chevron-up',
'icon_dark' => '',
'icon_light' => '',
'text' => __('顶部', 'aksrt'),
+2 -2
View File
@@ -70,7 +70,7 @@ class PostDisplay {
'scale' => max(20, min(200, (int) ($card_option['scale'] ?? 70))),
],
'mult_thumb_cat' => is_array($settings['mult_thumb_cat'] ?? null) ? array_values(array_filter(array_map('intval', $settings['mult_thumb_cat']))) : [],
'ajax_trigger' => wp_kses_post((string) ($settings['ajax_trigger'] ?? '<i class="fa fa-angle-right"></i>加载更多')),
'ajax_trigger' => wp_kses_post((string) ($settings['ajax_trigger'] ?? '<i class="fa fas fa-angle-right"></i>加载更多')),
'ajax_nomore' => wp_kses_post((string) ($settings['ajax_nomore'] ?? '没有更多内容了')),
];
}
@@ -412,7 +412,7 @@ class PostDisplay {
if (is_admin() || !($query instanceof \WP_Query) || !$query->is_main_query()) {
return;
}
if (!$query->is_home() && !$query->is_archive() && !$query->is_search()) {
if (!$query->is_home() && !$query->is_archive()) {
return;
}
if ($query->get('orderby')) {
+5 -16
View File
@@ -77,6 +77,9 @@ class Settings {
// 搜索结果排除(search_no_page / search_exclude_cats)
add_action('pre_get_posts', [self::class, 'filter_search_query']);
add_filter('posts_search', [ThemeSearch::class, 'filter_posts_search'], 50, 2);
add_filter('posts_join', [ThemeSearch::class, 'filter_posts_search_join'], 50, 2);
add_filter('posts_distinct', [ThemeSearch::class, 'filter_posts_search_distinct'], 50, 2);
// 全局列表默认排序(list_orderby)
add_action('pre_get_posts', [self::class, 'apply_list_orderby']);
@@ -236,13 +239,6 @@ class Settings {
/** 获取搜索模式 */
public static function search_mode(): string {
return ThemeSearch::search_mode();
}
/** 是否启用搜索历史 */
public static function search_history_enabled(): bool {
return ThemeSearch::search_history_enabled();
@@ -278,13 +274,6 @@ class Settings {
/** 是否启用搜索建议 */
public static function search_suggestions_enabled(): bool {
return ThemeSearch::search_suggestions_enabled();
}
/** 是否在搜索面板显示热门文章 */
public static function search_posts_enabled(): bool {
return ThemeSearch::search_posts_enabled();
@@ -320,8 +309,8 @@ class Settings {
/** 是否显示更多分类 */
public static function search_more_cat_obj(): bool {
/** 允许用户选择的更多分类 ID */
public static function search_more_cat_obj(): array {
return ThemeSearch::search_more_cat_obj();
}
+168 -81
View File
@@ -14,31 +14,22 @@ class ThemeSearch {
return $placeholder !== '' ? $placeholder : __('开启精彩搜索', 'aksrt');
}
public static function search_mode(): string {
$mode = sanitize_key((string) Settings::get_value('search_mode', ''));
if ($mode === '' || !in_array($mode, ['default', 'ajax', 'redirect'], true)) {
$mode = sanitize_key((string) Settings::get_value('search_type', 'default'));
}
return in_array($mode, ['default', 'ajax', 'redirect'], true) ? $mode : 'default';
}
public static function search_history_enabled(): bool {
$settings = Settings::get_all();
return !array_key_exists('search_history_enabled', $settings) || !empty($settings['search_history_enabled']);
return !array_key_exists('search_history', $settings) || !empty($settings['search_history']);
}
public static function hot_search_enabled(): bool {
$settings = Settings::get_all();
return !array_key_exists('hot_search_enabled', $settings) || !empty($settings['hot_search_enabled']);
return !array_key_exists('search_popular_key', $settings) || !empty($settings['search_popular_key']);
}
public static function hot_search_keywords(): array {
$raw = Settings::get_value('hot_search_keywords', '');
if (is_array($raw)) {
$items = $raw;
} else {
$items = preg_split('/[\r\n,]+/', (string) $raw) ?: [];
}
$items = self::search_popular_sticky();
$counts = get_option('search_keywords', []);
if (is_array($counts)) {
$items = array_merge($items, array_keys($counts));
}
$items = array_map(
static function ($keyword): string {
@@ -66,16 +57,12 @@ class ThemeSearch {
if (is_array($raw)) {
$items = $raw;
} else {
$items = preg_split('/[\r\n,]+/', (string) $raw) ?: [];
$items = preg_split('/[\r\n,,]+/', (string) $raw) ?: [];
}
$items = array_map(static fn($k) => trim(sanitize_text_field((string) $k)), $items);
return array_values(array_filter(array_unique($items), fn(string $k) => $k !== ''));
}
public static function search_suggestions_enabled(): bool {
return self::search_mode() === 'ajax' && !empty(Settings::get_value('search_suggestions_enabled', false));
}
public static function search_posts_enabled(): bool {
return !empty(Settings::get_value('search_posts', false));
}
@@ -103,8 +90,10 @@ class ThemeSearch {
return trim((string) Settings::get_value('search_cat_in', ''));
}
public static function search_more_cat_obj(): bool {
return !empty(Settings::get_value('search_more_cat_obj', true));
public static function search_more_cat_obj(): array {
$raw = Settings::get_value('search_more_cat_obj', []);
$items = is_array($raw) ? $raw : (preg_split('/[,,\s]+/', (string) $raw) ?: []);
return array_values(array_filter(array_unique(array_map('absint', $items))));
}
public static function search_custom_key_enabled(): bool {
@@ -112,42 +101,47 @@ class ThemeSearch {
}
public static function search_custom_key(): array {
$raw = Settings::get_value('search_custom_key', 'title,content');
$raw = Settings::get_value('search_custom_key', ['title', 'content', 'excerpt', 'post_tag', 'forum_topic', 'shop_cat', 'shop_discount']);
if (is_array($raw)) {
$items = $raw;
} else {
$items = preg_split('/[,,\s]+/', (string) $raw) ?: [];
}
$items = array_map(static fn($k) => trim(sanitize_key((string) $k)), $items);
$valid = ['title', 'content', 'excerpt', 'category', 'tag', 'author'];
$valid = ['title', 'content', 'excerpt', 'category', 'post_tag', 'topics', 'coment', 'user', 'forum_topic', 'forum_tag', 'shop_cat', 'shop_tag', 'shop_discount'];
return array_values(array_intersect(array_filter(array_unique($items)), $valid));
}
public static function search_facets_enabled(): bool {
return !empty(Settings::get_value('search_facets', false));
return !empty(Settings::get_value('search_facets', []));
}
public static function search_facets_order(): array {
$raw = Settings::get_value('search_facets_order', "category\ntag");
$items = is_array($raw) ? $raw : (preg_split('/[\r\n]+/', (string) $raw) ?: []);
$items = array_map(static fn($s) => trim(sanitize_key((string) $s)), $items);
$raw = Settings::get_value('search_facets', []);
$items = is_array($raw) ? array_keys($raw) : [];
$items = array_map(static fn($s) => trim(sanitize_key((string) $s)), $items);
return array_values(array_filter(array_unique($items), fn(string $s) => $s !== ''));
}
public static function get_meilisearch_config(): array {
$s = Settings::get_all();
$s = Settings::get_all();
$opt = is_array($s['search_ms_opt'] ?? null) ? $s['search_ms_opt'] : [];
$enabled = !empty($s['search_ms_enabled']);
$api_url = esc_url_raw(trim((string) ($s['search_ms_api_url'] ?? '')));
$api_key = sanitize_text_field((string) ($s['search_ms_api_key'] ?? ''));
$index_prefix = sanitize_key((string) ($s['search_ms_index_prefix'] ?? 'aksrt'));
$synonyms_raw = trim((string) ($s['search_ms_synonyms'] ?? ''));
$synonyms = [];
if ($synonyms_raw !== '') {
$decoded = json_decode($synonyms_raw, true);
if (is_array($decoded)) {
$synonyms = $decoded;
}
$enabled = !empty($s['search_ms_s']);
$api_url = esc_url_raw(trim((string) ($opt['api_url'] ?? 'http://127.0.0.1:7700')));
$api_key = sanitize_text_field((string) ($opt['api_key'] ?? ''));
$index_prefix = sanitize_key((string) ($opt['index_prefix'] ?? 'aksrt'));
$synonyms_raw = $opt['synonyms'] ?? [];
$synonyms = [];
foreach ((array) $synonyms_raw as $row) {
if (!is_array($row)) {
continue;
}
$key = trim(sanitize_text_field((string) ($row['key'] ?? '')));
$values = array_values(array_filter(array_map('trim', explode(',', sanitize_text_field((string) ($row['val'] ?? ''))))));
if ($key !== '' && $values) {
$synonyms[$key] = $values;
}
}
return [
@@ -156,15 +150,96 @@ class ThemeSearch {
'api_key' => $api_key,
'index_prefix' => $index_prefix !== '' ? $index_prefix : 'aksrt',
'synonyms' => $synonyms,
'index_name' => ($index_prefix !== '' ? $index_prefix : 'aksrt') . '_posts',
];
}
'index_name' => ($index_prefix !== '' ? $index_prefix : 'aksrt') . '_posts',
];
}
public static function filter_posts_search(string $search, \WP_Query $query): string {
if (!$query->is_search() || !$query->get('s') || !self::search_custom_key_enabled()) {
return $search;
}
if (sanitize_key((string) $query->get('type')) === 'user') {
return ' AND 1=0';
}
$config = self::get_meilisearch_config();
if (!empty($config['enabled'])) {
return $search;
}
$keys = self::search_custom_key();
if (!$keys) {
return $search;
}
global $wpdb;
$terms = (array) ($query->query_vars['search_terms'] ?? []);
if (!$terms) {
$terms = [(string) $query->get('s')];
}
$groups = [];
$taxonomies = ['post_tag', 'category', 'topics', 'forum_tag', 'forum_topic', 'shop_tag', 'shop_cat', 'shop_discount'];
foreach ($terms as $term) {
$like = (!empty($query->query_vars['exact']) ? '' : '%') . $wpdb->esc_like((string) $term) . (!empty($query->query_vars['exact']) ? '' : '%');
$parts = [];
foreach ($keys as $key) {
if ($key === 'title') $parts[] = $wpdb->prepare("{$wpdb->posts}.post_title LIKE %s", $like);
elseif ($key === 'content') $parts[] = $wpdb->prepare("{$wpdb->posts}.post_content LIKE %s", $like);
elseif ($key === 'excerpt') $parts[] = $wpdb->prepare("{$wpdb->posts}.post_excerpt LIKE %s", $like);
elseif (in_array($key, $taxonomies, true)) $parts[] = $wpdb->prepare('(aksrt_search_tt.taxonomy = %s AND aksrt_search_terms.name LIKE %s)', $key, $like);
elseif ($key === 'coment') $parts[] = $wpdb->prepare('aksrt_search_comments.comment_content LIKE %s', $like);
elseif ($key === 'user') $parts[] = $wpdb->prepare('(aksrt_search_users.user_nicename LIKE %s OR aksrt_search_users.display_name LIKE %s)', $like, $like);
}
if ($parts) {
$groups[] = '(' . implode(' OR ', $parts) . ')';
}
}
if (!$groups) {
return $search;
}
if (!is_user_logged_in()) {
$groups[] = "({$wpdb->posts}.post_password = '')";
}
return ' AND ' . implode(' AND ', $groups);
}
public static function filter_posts_search_join(string $join, \WP_Query $query): string {
if (!$query->is_search() || !$query->get('s') || !self::search_custom_key_enabled() || !empty(self::get_meilisearch_config()['enabled'])) {
return $join;
}
global $wpdb;
$keys = self::search_custom_key();
if (in_array('coment', $keys, true)) {
$join .= " LEFT JOIN {$wpdb->comments} AS aksrt_search_comments ON ({$wpdb->posts}.ID = aksrt_search_comments.comment_post_ID)";
}
if (in_array('user', $keys, true)) {
$join .= " LEFT JOIN {$wpdb->users} AS aksrt_search_users ON ({$wpdb->posts}.post_author = aksrt_search_users.ID)";
}
if (array_intersect(['post_tag', 'category', 'topics', 'forum_tag', 'forum_topic', 'shop_tag', 'shop_cat', 'shop_discount'], $keys)) {
$join .= " LEFT JOIN {$wpdb->term_relationships} AS aksrt_search_tr ON ({$wpdb->posts}.ID = aksrt_search_tr.object_id)";
$join .= " LEFT JOIN {$wpdb->term_taxonomy} AS aksrt_search_tt ON (aksrt_search_tr.term_taxonomy_id = aksrt_search_tt.term_taxonomy_id)";
$join .= " LEFT JOIN {$wpdb->terms} AS aksrt_search_terms ON (aksrt_search_tt.term_id = aksrt_search_terms.term_id)";
}
return $join;
}
public static function filter_posts_search_distinct(string $distinct, \WP_Query $query): string {
return $query->is_search() && $query->get('s') && self::search_custom_key_enabled() ? 'DISTINCT' : $distinct;
}
public static function filter_search_query($query): void {
if (is_admin() || !$query->is_main_query() || !$query->is_search()) {
return;
}
$type = isset($_REQUEST['type']) ? sanitize_key((string) wp_unslash($_REQUEST['type'])) : '';
if (!in_array($type, ['post', 'user'], true)) {
$type = self::get_search_content_types()['default'];
}
$query->set('type', $type);
if ($type === 'user') {
$query->set('post__in', [0]);
return;
}
if (self::search_no_page()) {
$existing = $query->get('post_type');
if (empty($existing)) {
@@ -174,17 +249,52 @@ class ThemeSearch {
$exclude_cats = self::search_exclude_cats();
if (!empty($exclude_cats)) {
$cat_query = $query->get('cat');
$negatives = array_map(fn(int $id) => -$id, $exclude_cats);
if (!empty($cat_query)) {
$existing = is_array($cat_query) ? $cat_query : explode(',', (string) $cat_query);
$existing = array_map('intval', $existing);
$merged = array_merge($existing, $negatives);
$query->set('cat', implode(',', array_unique($merged)));
} else {
$query->set('cat', implode(',', $negatives));
foreach ($exclude_cats as $category_id) {
$children = get_term_children($category_id, 'category');
if (!is_wp_error($children)) {
$exclude_cats = array_merge($exclude_cats, $children);
}
}
$query->set('category__not_in', array_values(array_unique(array_map('absint', $exclude_cats))));
}
$term_id = isset($_REQUEST['trem']) ? absint(wp_unslash($_REQUEST['trem'])) : 0;
if ($term_id > 0) {
$term = get_term($term_id);
if ($term instanceof \WP_Term) {
$tax_query = (array) $query->get('tax_query');
$tax_query[] = [
'taxonomy' => $term->taxonomy,
'field' => 'term_id',
'terms' => $term->term_id,
];
$query->set('tax_query', $tax_query);
}
}
$user_id = isset($_REQUEST['user']) ? absint(wp_unslash($_REQUEST['user'])) : 0;
if ($user_id > 0) {
$query->set('author', $user_id);
}
$orderby = isset($_REQUEST['orderby']) ? sanitize_key((string) wp_unslash($_REQUEST['orderby'])) : '';
$meta_keys = [
'views' => 'aksrt_post_views',
'like' => '_aksrt_like_count',
'favorite' => '_aksrt_favorite_count',
'sales_volume' => '_aksrt_sales_volume',
];
if (isset($meta_keys[$orderby])) {
$query->set('meta_key', $meta_keys[$orderby]);
$query->set('orderby', ['meta_value_num' => 'DESC', 'date' => 'DESC']);
$query->set('order', 'DESC');
} elseif ($orderby === 'comment_count') {
$query->set('orderby', 'comment_count');
$query->set('order', 'DESC');
} elseif ($orderby === 'date') {
$query->set('orderby', 'date');
$query->set('order', 'DESC');
}
}
public static function apply_list_orderby($query): void {
@@ -221,37 +331,14 @@ class ThemeSearch {
}
public static function get_search_content_types(): array {
$all_types = [
'post' => 'search_type_post',
'user' => 'search_type_user',
'category' => 'search_type_category',
'tag' => 'search_type_tag',
];
$enabled = [];
$all = Settings::get_all();
foreach ($all_types as $type => $key) {
$default_on = in_array($type, ['post', 'category', 'tag'], true);
$is_enabled = array_key_exists($key, $all)
? !empty(Settings::get_value($key, $default_on))
: $default_on;
if ($is_enabled) {
$enabled[] = $type;
}
}
if (empty($enabled)) {
$enabled = ['post'];
}
$default = sanitize_key((string) Settings::get_value('search_default_type', 'post'));
if (!in_array($default, $enabled, true)) {
$default = $enabled[0];
$types = ['post', 'user'];
$default = sanitize_key((string) Settings::get_value('search_type_in', 'post'));
if (!in_array($default, $types, true)) {
$default = 'post';
}
return [
'types' => $enabled,
'types' => $types,
'default' => $default,
];
}