Files
wordpress-theme-aksrt/inc/helpers/search/aksrt-search-box.php
T

410 lines
16 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
/**
* Search box markup (legacy parity).
*
* Used by layout-2 menu_search AJAX panel and layout 1/3 .navbar-search.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
if (!function_exists('aksrt_save_history_search')) :
/** Store the legacy history_search cookie (newest first, maximum thirty). */
function aksrt_save_history_search(string $search): void {
$search = trim(wp_strip_all_tags($search));
$search_text = aksrt_get_search_keywords_text($search);
if ($search_text === '' || mb_strlen($search_text) >= 30 || headers_sent()) {
return;
}
$history = aksrt_get_search_history_keywords();
$history = array_values(array_filter($history, static function (string $item) use ($search_text): bool {
return aksrt_get_search_keywords_text($item) !== $search_text;
}));
array_unshift($history, $search);
$history = array_slice($history, 0, 30);
setcookie('history_search', wp_json_encode($history), [
'expires' => time() + MONTH_IN_SECONDS,
'path' => COOKIEPATH ?: '/',
'domain' => COOKIE_DOMAIN,
'secure' => is_ssl(),
'httponly' => false,
'samesite' => 'Lax',
]);
$_COOKIE['history_search'] = wp_json_encode($history);
}
endif;
if (!function_exists('aksrt_get_main_search')) :
/** legacy main-search defaults backed only by the reference option IDs. */
function aksrt_get_main_search(array $args = [], bool $echo = false) {
$settings = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_all() : [];
$search_cat = !array_key_exists('search_cat', $settings) || !empty($settings['search_cat']);
$search_type = !array_key_exists('search_type', $settings) || !empty($settings['search_type']);
$defaults = [
'class' => '',
'show_keywords' => !array_key_exists('search_popular_key', $settings) || !empty($settings['search_popular_key']),
'show_history' => !array_key_exists('search_history', $settings) || !empty($settings['search_history']),
'show_posts' => !array_key_exists('search_posts', $settings) || !empty($settings['search_posts']),
'show_input_cat' => $search_cat,
'more_cats' => $search_cat ? (array) ($settings['search_more_cat_obj'] ?? []) : [],
'in_cat' => $search_cat ? ($settings['search_cat_in'] ?? '') : '',
'show_type' => $search_type,
'in_type' => $search_type ? sanitize_key((string) ($settings['search_type_in'] ?? 'post')) : '',
'in_user' => '',
];
return aksrt_get_search_box(wp_parse_args($args, $defaults), $echo);
}
endif;
if (!function_exists('aksrt_get_search_history_keywords')) :
/**
* @return list<string>
*/
function aksrt_get_search_history_keywords(): array {
$raw = isset($_COOKIE['history_search'])
? wp_unslash((string) $_COOKIE['history_search'])
: '';
$decoded = $raw !== '' ? json_decode(stripslashes($raw), true) : [];
if (!is_array($decoded)) {
return [];
}
$hist = array_map(
static fn($item): string => sanitize_text_field((string) $item),
array_slice($decoded, 0, 30)
);
return array_values(array_unique(array_filter(array_map('trim', $hist))));
}
endif;
if (!function_exists('aksrt_get_search_keywords_text')) :
function aksrt_get_search_keywords_text(string $search): string {
$search = str_replace('&amp;type', '&type', $search);
$index = strpos($search, '&type=');
return trim($index === false ? $search : substr($search, 0, $index));
}
endif;
if (!function_exists('aksrt_update_search_keywords')) :
function aksrt_update_search_keywords(string $search): void {
$search = trim(wp_strip_all_tags($search));
$text = aksrt_get_search_keywords_text($search);
if (mb_strlen($text) < 2 || mb_strlen($text) > 8) {
return;
}
if (class_exists('\AKSRT\Settings\Settings') && !\AKSRT\Settings\Settings::hot_search_enabled()) {
return;
}
$keywords = get_option('search_keywords', []);
$keywords = is_array($keywords) ? $keywords : [];
$limit = class_exists('\AKSRT\Settings\Settings')
? max(10, min(50, (int) \AKSRT\Settings\Settings::get_value('search_popular_key_num', 20)))
: 20;
$keywords = array_slice($keywords, 0, $limit + 10, true);
$keywords[$search] = isset($keywords[$search]) ? (int) $keywords[$search] + 1 : 1;
arsort($keywords, SORT_NUMERIC);
update_option('search_keywords', $keywords, false);
}
endif;
if (!function_exists('aksrt_get_search_keywords_but')) :
/**
* Render keyword chip links.
*
* @param list<string> $keywords
* @param string $type popular|history
*/
function aksrt_get_search_keywords_but(array $keywords, string $type = 'popular', int $limit = 0): string {
if ($limit > 0) {
$keywords = array_slice($keywords, 0, $limit);
}
$out = '';
foreach ($keywords as $kw) {
$kw = trim((string) $kw);
if ($kw === '') {
continue;
}
$text = aksrt_get_search_keywords_text($kw);
$query = ['s' => $text];
if (preg_match('/&type=([a-z0-9_-]+)/i', $kw, $match)) {
$query['type'] = sanitize_key($match[1]);
}
$out .= '<a class="search_keywords muted-2-color but em09 mr6 mb6" data-search-keyword="' . esc_attr($kw) . '" href="'
. esc_url(add_query_arg($query, home_url('/'))) . '">'
. esc_html($text) . '</a> ';
}
return $out;
}
endif;
if (!function_exists('aksrt_get_search_box')) :
/**
* legacy-compatible search box.
*
* @param array<string,mixed> $args
* @param bool $echo
* @return string|void
*/
function aksrt_get_search_box(array $args = [], bool $echo = false) {
$defaults = [
's' => '',
'class' => '',
'show_form' => true,
'show_keywords' => true,
'popular_limit' => 0,
'show_history' => true,
'keywords_title' => '',
'placeholder' => '',
'show_input_cat' => true,
'show_posts' => false,
'show_type' => false,
'in_cat' => '',
'in_type' => 'post',
'in_user' => '',
'more_cats' => [],
];
$args = wp_parse_args($args, $defaults);
if ($args['keywords_title'] === '' && class_exists('\AKSRT\Settings\Settings')
&& method_exists('\AKSRT\Settings\Settings', 'search_popular_title')) {
$args['keywords_title'] = (string) \AKSRT\Settings\Settings::search_popular_title();
}
if ($args['keywords_title'] === '') {
$args['keywords_title'] = __('热门搜索', 'aksrt');
}
if ($args['placeholder'] === '' && function_exists('aksrt_get_search_placeholder')) {
$args['placeholder'] = aksrt_get_search_placeholder();
}
if ($args['placeholder'] === '') {
$args['placeholder'] = __('开启精彩搜索', 'aksrt');
}
$args['placeholder'] = esc_attr((string) $args['placeholder']);
$form_html = '';
if (!empty($args['show_form'])) {
$state = function_exists('aksrt_get_search_form_state')
? aksrt_get_search_form_state()
: [
'type' => 'post',
'types' => ['post' => __('文章', 'aksrt')],
'category_id' => 0,
'category_enabled' => false,
'categories' => [],
];
$cat_html = '';
$category_terms = [];
if (!empty($args['show_input_cat'])) {
$category_ids = is_array($args['more_cats'])
? $args['more_cats']
: (preg_split('/[,,\s]+/', (string) $args['more_cats']) ?: []);
if ($category_ids && function_exists('aksrt_get_search_categories')) {
$category_terms = aksrt_get_search_categories($category_ids);
}
if ((int) $args['in_cat'] > 0) {
$selected_term = get_term((int) $args['in_cat']);
if ($selected_term && !is_wp_error($selected_term)) {
$selected_term_name = (string) $selected_term->name;
if (!$category_terms) {
$category_terms = [$selected_term];
}
}
}
}
if ($category_terms) {
$in_cat_id = (int) $args['in_cat'];
$in_cat_name = $in_cat_id > 0 ? (string) ($selected_term_name ?? '') : '';
$all_cat = '<li data-for="trem" data-value="null"><a href="javascript:;" class="text-ellipsis">'
. esc_html__('全部', 'aksrt') . '</a></li>';
foreach ($category_terms as $cat) {
if (!$cat instanceof WP_Term) {
continue;
}
$cid = (int) $cat->term_id;
$cname = (string) $cat->name;
if ($cid <= 0 || $cname === '') {
continue;
}
if ($cid === $in_cat_id) {
$in_cat_name = $cname;
}
$all_cat .= '<li data-for="trem" data-value="' . esc_attr((string) $cid) . '"><a href="javascript:;" class="text-ellipsis">'
. esc_html(mb_strlen($cname) > 8 ? mb_substr($cname, 0, 8) . '…' : $cname)
. '</a></li>';
}
$all_cat = '<ul class="dropdown-menu cat-drop">' . $all_cat . '</ul>';
$label = $in_cat_name !== ''
? (mb_strlen($in_cat_name) > 6 ? mb_substr($in_cat_name, 0, 6) . '…' : $in_cat_name)
: __('请选择', 'aksrt');
$input_cat = '<a href="javascript:;" class="padding-h10" data-toggle="dropdown"><span name="trem">'
. esc_html($label) . '</span><i class="fa ml6 fa-sort opacity5" aria-hidden="true"></i></a>';
$input_cat .= $all_cat;
$cat_html = '<div class="option-dropdown splitters-this-r search-drop"><div class="dropdown">'
. $input_cat . '</div></div>';
}
$type_html = '';
$type_dropdown_html = '';
$types = is_array($state['types'] ?? null) ? $state['types'] : [];
$in_type = (string) ($args['in_type'] ?: ($state['type'] ?? 'post'));
if (!empty($args['show_type']) && count($types) > 1) {
$type_name = (string) ($types[$in_type] ?? reset($types));
if ($cat_html !== '') {
$type_items = '';
foreach ($types as $key => $label) {
$cls = $in_type === (string) $key ? ' active' : '';
$type_items .= '<a class="but' . esc_attr($cls) . '" data-for="type" data-value="'
. esc_attr((string) $key) . '" href="javascript:;">' . esc_html((string) $label) . '</a>';
}
$type_html = '<div class="flex jc mb10 search-type-but-average"><div class="but-average radius">'
. $type_items . '</div></div>';
} else {
$type_items = '';
foreach ($types as $key => $label) {
$type_items .= '<li><a href="javascript:;" class="text-ellipsis" data-for="type" data-value="'
. esc_attr((string) $key) . '">' . esc_html((string) $label) . '</a></li>';
}
$type_dropdown_html = '<div class="option-dropdown splitters-this-r search-drop"><div class="dropdown">'
. '<a href="javascript:;" class="padding-h10" data-toggle="dropdown"><span name="type">'
. esc_html($type_name) . '</span><i class="fa ml6 fa-sort opacity5" aria-hidden="true"></i></a>'
. '<ul class="dropdown-menu">' . $type_items . '</ul></div></div>';
}
}
$s = esc_attr(wp_strip_all_tags((string) $args['s']));
$input_html = '<div class="search-input-text">';
$input_html .= '<input type="text" name="s" class="line-form-input" tabindex="1" value="' . $s . '">';
$input_html .= '<i class="line-form-line"></i>';
$input_html .= '<div class="scale-placeholder' . ($s !== '' ? ' is-focus' : '') . '" default="'
. $args['placeholder'] . '">' . $args['placeholder'] . '</div>';
$input_html .= '<div class="abs-right muted-color"><button type="submit" tabindex="2" class="null" aria-label="'
. esc_attr__('搜索', 'aksrt') . '"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-search"></use></svg></button></div>';
$input_html .= '</div>';
$input_html .= '<input type="hidden" name="type" value="' . esc_attr($in_type) . '">';
if ($cat_html !== '' || (string) $args['in_cat'] !== '') {
$input_html .= '<input type="hidden" name="trem" value="'
. esc_attr((string) $args['in_cat']) . '">';
}
if ((string) $args['in_user'] !== '') {
$input_html .= '<input type="hidden" name="user" value="' . esc_attr((string) $args['in_user']) . '">';
}
$form_html = '<form method="get" class="padding-10 search-form" action="'
. esc_url(home_url('/')) . '">'
. $type_html
. '<div class="line-form">' . ($cat_html !== '' ? $cat_html : $type_dropdown_html) . $input_html . '</div>'
. '</form>';
}
// Popular keywords.
$keywords_html = '';
if (!empty($args['show_keywords'])) {
$show = true;
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'hot_search_enabled')) {
$show = (bool) \AKSRT\Settings\Settings::hot_search_enabled();
}
if ($show) {
$keywords = function_exists('aksrt_get_search_hot_keywords') ? aksrt_get_search_hot_keywords() : [];
$limit = (int) $args['popular_limit'];
$keyword_link = aksrt_get_search_keywords_but(is_array($keywords) ? $keywords : [], 'popular', $limit);
if ($keyword_link !== '') {
$keywords_html = '<div class="search-keywords">'
. '<p class="muted-color"><span>' . esc_html((string) $args['keywords_title']) . '</span></p>'
. '<div>' . $keyword_link . '</div>'
. '</div>';
}
}
}
// History.
$history_html = '';
if (!empty($args['show_history'])) {
$show_h = true;
if (function_exists('aksrt_search_history_enabled')) {
$show_h = aksrt_search_history_enabled();
} elseif (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'search_history_enabled')) {
$show_h = (bool) \AKSRT\Settings\Settings::search_history_enabled();
}
if ($show_h) {
$hist = aksrt_get_search_history_keywords();
$keyword_link = aksrt_get_search_keywords_but($hist, 'history');
if ($keyword_link !== '') {
$history_html = '<div class="search-keywords history-search">';
$history_html .= '<p class="muted-color"><span>' . esc_html__('历史搜索', 'aksrt') . '</span>';
$history_html .= '<a class="pull-right trash-history-search muted-3-color" href="javascript:;" data-cookie-path="'
. esc_attr(COOKIEPATH ?: '/') . '" data-cookie-domain="' . esc_attr(COOKIE_DOMAIN) . '" aria-label="'
. esc_attr__('清空历史', 'aksrt') . '"><i class="fa fas fa-trash-alt em12" aria-hidden="true"></i></a></p>';
$history_html .= '<div>' . $keyword_link . '</div></div>';
}
}
}
// Hot posts (thumb swiper).
$posts_html = '';
if (!empty($args['show_posts'])) {
$show_p = true;
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'search_posts_enabled')) {
$show_p = (bool) \AKSRT\Settings\Settings::search_posts_enabled();
}
if ($show_p && function_exists('aksrt_get_search_posts')) {
$slides = aksrt_get_search_posts(6, 'views', true);
if ($slides !== '') {
$posts_html = '<div class="padding-10 relates relates-thumb">';
$posts_html .= '<p class="muted-color">' . esc_html__('热门文章', 'aksrt') . '</p>';
$posts_html .= '<div class="swiper-container swiper-scroll">';
$posts_html .= '<div class="swiper-wrapper">' . $slides . '</div>';
$posts_html .= '<div class="swiper-button-prev"></div><div class="swiper-button-next"></div>';
$posts_html .= '</div></div>';
}
}
}
$class_tokens = preg_split('/\s+/', trim((string) $args['class'])) ?: [];
$class_tokens = array_values(array_filter(array_map('sanitize_html_class', $class_tokens)));
$class = $class_tokens ? ' ' . implode(' ', $class_tokens) : '';
$html = '<div class="search-input' . esc_attr($class) . '">'
. $form_html . $keywords_html . $history_html . $posts_html
. '</div>';
if ($echo) {
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return;
}
return $html;
}
endif;
if (!function_exists('aksrt_get_remote_box')) :
/**
* Lazy remote HTML mount (legacy).
*
* @param array<string,mixed> $args
*/
function aksrt_get_remote_box(array $args = []): string {
$defaults = [
'type' => 'ias',
'class' => '',
'loader' => '<i class="loading-spot"><i></i></i>',
'url' => admin_url('admin-ajax.php'),
'query' => false,
];
$args = wp_parse_args($args, $defaults);
$url = (string) $args['url'];
if (!empty($args['query']) && is_array($args['query'])) {
$url = add_query_arg($args['query'], $url);
}
$attr = ' remote-box="' . esc_url($url) . '"';
$class = (string) $args['class'];
if (($args['type'] ?? '') === 'ias') {
$attr .= ' lazyload-action="ias"';
$class .= ' lazyload';
}
if (($args['type'] ?? '') === 'load') {
$attr .= ' load-click';
}
$class_attr = $class !== '' ? ' class="' . esc_attr(trim($class)) . '"' : '';
return '<div' . $class_attr . $attr . '>' . $args['loader'] . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
endif;