- Layout-2 remote-box AJAX panel (history/hot/posts) via aksrt_menu_search - Live suggestions for post/topic/product; local history for guests - Publish radius switch (zibll bool pill) mapped to CSS radius class - Senior menu editor: WP media library image picker - Active menu underline + panel CSS; acceptance/contract updates
142 lines
5.2 KiB
PHP
142 lines
5.2 KiB
PHP
<?php
|
|
/**
|
|
* Layout-2 menu search remote panel (zibll menu_search parity subset).
|
|
*
|
|
* @package AKSRT
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
if (!function_exists('aksrt_ajax_menu_search')) :
|
|
/**
|
|
* AJAX: HTML panel for navbar inline search (history + hot + posts).
|
|
*/
|
|
function aksrt_ajax_menu_search(): void {
|
|
// Prefer public nonce; also accept no nonce for same-origin remote-box first paint like zibll.
|
|
if (!empty($_REQUEST['nonce'])) {
|
|
$nonce = sanitize_text_field(wp_unslash((string) $_REQUEST['nonce']));
|
|
if (!wp_verify_nonce($nonce, 'aksrt_public_nonce')) {
|
|
wp_die('0');
|
|
}
|
|
}
|
|
|
|
$html = aksrt_get_menu_search_panel_html();
|
|
if ($html === '') {
|
|
wp_die('0');
|
|
}
|
|
|
|
echo '<div class="dropdown-menu hover-show-con navbar-inline-search-panel is-open">' . $html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
wp_die();
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_get_menu_search_panel_html')) :
|
|
/**
|
|
* Build inner search panel HTML (no outer dropdown wrapper).
|
|
*/
|
|
function aksrt_get_menu_search_panel_html(): string {
|
|
$show_keywords = true;
|
|
$show_history = true;
|
|
$show_posts = true;
|
|
if (class_exists('\AKSRT\Settings\Settings')) {
|
|
$show_keywords = method_exists('\AKSRT\Settings\Settings', 'hot_search_enabled')
|
|
? (bool) \AKSRT\Settings\Settings::hot_search_enabled()
|
|
: true;
|
|
$show_history = method_exists('\AKSRT\Settings\Settings', 'search_history_enabled')
|
|
? (bool) \AKSRT\Settings\Settings::search_history_enabled()
|
|
: true;
|
|
$show_posts = method_exists('\AKSRT\Settings\Settings', 'search_posts_enabled')
|
|
? (bool) \AKSRT\Settings\Settings::search_posts_enabled()
|
|
: !empty(\AKSRT\Settings\Settings::get_value('search_posts', true));
|
|
}
|
|
|
|
$out = '';
|
|
|
|
// History (client may also fill via localStorage; server returns logged-in history).
|
|
if ($show_history) {
|
|
$hist = [];
|
|
if (is_user_logged_in()) {
|
|
$saved = get_user_meta(get_current_user_id(), 'aksrt_search_history', true);
|
|
if (is_array($saved)) {
|
|
foreach (array_slice($saved, 0, 10) as $item) {
|
|
if (is_array($item) && !empty($item['keyword'])) {
|
|
$hist[] = (string) $item['keyword'];
|
|
} elseif (is_string($item) && $item !== '') {
|
|
$hist[] = $item;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$out .= '<div class="aksrt-menu-search-history" data-aksrt-menu-history="1">';
|
|
$out .= '<div class="flex jsb ac mb6"><span class="muted-2-color em09">' . esc_html__('搜索历史', 'aksrt') . '</span>';
|
|
$out .= '<a href="javascript:;" class="muted-2-color em09" data-aksrt-clear-menu-history="1">' . esc_html__('清空', 'aksrt') . '</a></div>';
|
|
$out .= '<div class="aksrt-menu-search-history__list">';
|
|
if ($hist) {
|
|
foreach ($hist as $kw) {
|
|
$out .= '<a class="but jb-sm" href="' . esc_url(home_url('/?s=' . rawurlencode($kw))) . '">' . esc_html($kw) . '</a> ';
|
|
}
|
|
} else {
|
|
$out .= '<span class="muted-3-color em09" data-empty="1">' . esc_html__('暂无历史', 'aksrt') . '</span>';
|
|
}
|
|
$out .= '</div></div>';
|
|
}
|
|
|
|
// Hot keywords.
|
|
if ($show_keywords) {
|
|
$hots = function_exists('aksrt_get_search_hot_keywords') ? aksrt_get_search_hot_keywords() : [];
|
|
if ($hots) {
|
|
$title = class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'search_popular_title')
|
|
? \AKSRT\Settings\Settings::search_popular_title()
|
|
: __('热门搜索', 'aksrt');
|
|
$out .= '<div class="aksrt-menu-search-hots mt10">';
|
|
$out .= '<div class="muted-2-color em09 mb6">' . esc_html($title) . '</div>';
|
|
$out .= '<div class="navbar-inline-search-hots">';
|
|
foreach ($hots as $kw) {
|
|
$kw = trim((string) $kw);
|
|
if ($kw === '') {
|
|
continue;
|
|
}
|
|
$out .= '<a class="but jb-sm" href="' . esc_url(home_url('/?s=' . rawurlencode($kw))) . '">' . esc_html($kw) . '</a> ';
|
|
}
|
|
$out .= '</div></div>';
|
|
}
|
|
}
|
|
|
|
// Latest / popular posts (optional).
|
|
if ($show_posts) {
|
|
$posts = get_posts([
|
|
'post_type' => 'post',
|
|
'post_status' => 'publish',
|
|
'posts_per_page' => 6,
|
|
'ignore_sticky_posts' => true,
|
|
'no_found_rows' => true,
|
|
'update_post_meta_cache' => false,
|
|
'update_post_term_cache' => false,
|
|
]);
|
|
if ($posts) {
|
|
$out .= '<div class="aksrt-menu-search-posts mt10">';
|
|
$out .= '<div class="muted-2-color em09 mb6">' . esc_html__('推荐内容', 'aksrt') . '</div>';
|
|
$out .= '<div class="aksrt-menu-search-posts__list">';
|
|
foreach ($posts as $p) {
|
|
$out .= '<a class="aksrt-menu-search-posts__item" href="' . esc_url(get_permalink($p)) . '">';
|
|
$out .= '<span class="title text-ellipsis">' . esc_html(get_the_title($p)) . '</span>';
|
|
$out .= '<span class="meta muted-3-color em09">' . esc_html(get_the_date('', $p)) . '</span>';
|
|
$out .= '</a>';
|
|
}
|
|
$out .= '</div></div>';
|
|
}
|
|
}
|
|
|
|
// Live suggestions mount point.
|
|
$out .= '<div class="aksrt-menu-search-suggest mt10" data-aksrt-menu-suggest="1" hidden></div>';
|
|
|
|
return $out;
|
|
}
|
|
endif;
|
|
|
|
add_action('wp_ajax_aksrt_menu_search', 'aksrt_ajax_menu_search');
|
|
add_action('wp_ajax_nopriv_aksrt_menu_search', 'aksrt_ajax_menu_search');
|
|
// Alias for zibll-compatible remote-box query action name used in markup.
|
|
add_action('wp_ajax_menu_search', 'aksrt_ajax_menu_search');
|
|
add_action('wp_ajax_nopriv_menu_search', 'aksrt_ajax_menu_search');
|