新的搜索功能,专门用于搜索产品标题:
// 添加搜索和筛选字段
function add_product_search_filters() {
global $pagenow;
if ($pagenow !== 'edit.php' || !isset($_GET['post_type']) || $_GET['post_type'] !== 'product') {
return;
}
$title_search = isset($_GET['title_search']) ? sanitize_text_field($_GET['title_search']) : '';
$exclude_cat = isset($_GET['exclude_category']) ? intval($_GET['exclude_category']) : '';
$tag_filter = isset($_GET['tag_filter']) ? sanitize_text_field($_GET['tag_filter']) : '';
?>
<div class="product-filters" style="display: inline-block; margin: 0 4px;">
<input type="text"
name="title_search"
value="<?php echo esc_attr($title_search); ?>"
placeholder="搜索产品标题"
style="margin-right: 4px;">
<select name="exclude_category" style="margin-right: 4px;">
<option value="">显示所有分类</option>
<?php display_categories_recursive(); ?>
</select>
<select name="tag_filter" style="margin-right: 4px;">
<option value="">全部产品</option>
<option value="has_tag" <?php selected($tag_filter, 'has_tag'); ?>>有标签</option>
<option value="no_tag" <?php selected($tag_filter, 'no_tag'); ?>>无标签</option>
</select>
</div>
<?php
}
add_action('restrict_manage_posts', 'add_product_search_filters');
// 递归显示分类
function display_categories_recursive($parent = 0, $level = 0) {
global $exclude_cat;
$terms = get_terms(array(
'taxonomy' => 'product_cat',
'hide_empty' => false,
'parent' => $parent
));
foreach($terms as $term) {
$indent = str_repeat(' ', $level);
echo '<option value="' . esc_attr($term->term_id) . '" '
. selected($exclude_cat, $term->term_id, false) . '>'
. $indent . '排除: ' . esc_html($term->name)
. '</option>';
display_categories_recursive($term->term_id, $level + 1);
}
}
// 处理搜索和筛选查询
function handle_product_search_query($query) {
global $pagenow;
if (!is_admin()
|| $pagenow !== 'edit.php'
|| !isset($_GET['post_type'])
|| $_GET['post_type'] !== 'product'
|| !$query->is_main_query()) {
return $query;
}
$tax_query = array();
// 处理标题搜索
if (isset($_GET['title_search']) && !empty($_GET['title_search'])) {
$query->query_vars['meta_query'] = array();
$query->query_vars['s'] = '';
$query->query_vars['search_prod_title'] = sanitize_text_field($_GET['title_search']);
add_filter('posts_where', 'filter_product_title', 10, 2);
}
// 处理分类排除
if (isset($_GET['exclude_category']) && !empty($_GET['exclude_category'])) {
$exclude_cat_id = intval($_GET['exclude_category']);
$exclude_cats = array($exclude_cat_id);
$child_terms = get_term_children($exclude_cat_id, 'product_cat');
if (!is_wp_error($child_terms)) {
$exclude_cats = array_merge($exclude_cats, $child_terms);
}
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $exclude_cats,
'operator' => 'NOT IN'
);
}
// 处理标签筛选
if (isset($_GET['tag_filter']) && !empty($_GET['tag_filter'])) {
switch($_GET['tag_filter']) {
case 'has_tag':
$tax_query[] = array(
'taxonomy' => 'product_tag',
'operator' => 'EXISTS'
);
break;
case 'no_tag':
$tax_query[] = array(
'taxonomy' => 'product_tag',
'operator' => 'NOT EXISTS'
);
break;
}
}
// 应用tax_query
if (!empty($tax_query)) {
if (count($tax_query) > 1) {
$tax_query['relation'] = 'AND';
}
$query->set('tax_query', $tax_query);
}
return $query;
}
add_filter('pre_get_posts', 'handle_product_search_query');
// 标题搜索过滤器
function filter_product_title($where, $wp_query) {
global $wpdb;
if ($search_term = $wp_query->get('search_prod_title')) {
$search_terms = array_filter(array_map('trim', explode(' ', $search_term)));
$title_where = array();
foreach($search_terms as $term) {
if(!empty($term)) {
if(is_numeric($term)) {
$title_where[] = $wpdb->prepare(
"({$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_title LIKE %s)",
$term . ' %',
'% ' . $term . ' %',
'% ' . $term,
'% ' . $term . '-'
);
} else {
$title_where[] = $wpdb->prepare(
"({$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_title LIKE %s)",
$term . ' %',
'% ' . $term . ' %',
'% ' . $term
);
}
}
}
if (!empty($title_where)) {
$where .= " AND (" . implode(' AND ', $title_where) . ")";
}
}
remove_filter('posts_where', 'filter_product_title', 10);
return $where;
}
// 添加样式
function add_product_filter_styles() {
global $pagenow;
if ($pagenow === 'edit.php' && isset($_GET['post_type']) && $_GET['post_type'] === 'product') {
?>
<style>
.product-filters select,
.product-filters input[type="text"] {
min-width: 150px;
height: 30px;
vertical-align: middle;
}
</style>
<?php
}
}
add_action('admin_head', 'add_product_filter_styles');
功能说明:
- 如果一个产品属于多个类目
- 只要其中一个类目被排除
- 该产品就不会显示在结果中
- 不管它是否同时属于其他未被排除的类目
- 标签筛选(有标签/无标签)
比如:
- 产品同时属于类目A和类目B
- 当排除类目B时
- 这个产品将不会显示在结果中
- 即使它也属于类目A