File: /www/wwwroot/www.sceybwg.com/wp-content/themes/Modular/public/post-filter.php
<?php
/**
* @Author: 大胡子
* @Email: dahuzi@xintheme.com
* @Link: www.xintheme.com
* @Date: 2022-09-25 17:02:34
* @Last Modified by: dahuzi
* @Last Modified time: 2024-10-24 18:20:04
*/
/** --------------------------------------------------------------------------------- *
* 多重筛选 专用菜单
* --------------------------------------------------------------------------------- */
class Dahuzi_Filter_Walker_Menu extends Walker_Nav_Menu {
// 开始渲染子菜单(即二级菜单)
function start_lvl(&$output, $depth = 0, $args = null) {
$indent = str_repeat("\t", $depth); // 缩进
$classes = ['sub-menu']; // 子菜单的 CSS 类
$class_names = join(' ', apply_filters('nav_menu_submenu_css_class', $classes, $args, $depth));
$class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';
$output .= "\n" . $indent . '<ul' . $class_names . '>' . "\n"; // 输出子菜单的 <ul> 标签
}
// 开始渲染菜单项
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
$indent = ($depth) ? str_repeat("\t", $depth) : ''; // 缩进
$class_names = $value = '';
// 提取菜单项的类
$classes = empty($item->classes) ? array() : (array) $item->classes;
if ($depth == 0) {
$custom_classes = array_filter($classes, function($class) {
// 过滤掉 WordPress 自动添加的类,保留自定义类
return strpos($class, 'menu-item') === false && strpos($class, 'current-menu') === false;
});
// 如果存在自定义类名,添加到 class 属性中
if (!empty($custom_classes)) {
$class_names = ' class="' . esc_attr(join(' ', $custom_classes)) . '"';
$class_names = ($class_names != ' class=""') ? $class_names : ''; //多这一步 只为了移除空白的class属性
}
// 对于一级菜单项,使用 <h3> 标签
//$output .= $indent . '<li id="menu-item-' . $item->ID . '"' . $value . $class_names . '>';
$output .= $indent . '<li' . $class_names . '>';
$output .= '<h3>'; // 开始 <h3> 标签
} else {
// 对于二级及以下菜单项,使用 <li> 标签
//$output .= $indent . '<li id="menu-item-' . $item->ID . '"' . $value . $class_names . '>';
$output .= $indent . '<li>';
}
// 添加菜单项的属性
$attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : '';
if ($item->object == 'post_tag') {
// 如果是标签菜单项
$tags = get_term_by('id', $item->object_id, 'post_tag');
$attributes .= ' value="' . $tags->term_id . '"';
$attributes .= ' name="tag"';
} else {
// 如果是分类菜单项
$attributes .= ' value="' . $item->object_id . '"';
$attributes .= ' name="cat"';
}
// 生成菜单项的输出
$item_output = $args->before;
if ($depth == 0) {
// For top-level items, place the label inside <h3>
$item_output .= apply_filters( 'the_title', $item->title, $item->ID );
} else {
// For sub-items, place the label inside <li>
$item_output .= '<label><input' . $attributes . ' type="checkbox" title="' . apply_filters( 'the_title', $item->title, $item->ID ) . '"><span>';
$item_output .= apply_filters( 'the_title', $item->title, $item->ID );
$item_output .= '</span></label>';
}
$item_output .= $args->link_before . $args->link_after;
if ($depth == 0) {
// 结束 <h3> 标签
$item_output .= '</h3>';
}
$item_output .= $args->after;
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args, $id);
}
// 结束渲染菜单项
function end_el(&$output, $item, $depth = 0, $args = null) {
$indent = ($depth) ? str_repeat("\t", $depth) : ''; // 缩进
$output .= $indent . '</li>' . "\n"; // 结束 <li> 标签
}
// 结束渲染子菜单(即二级菜单)
function end_lvl(&$output, $depth = 0, $args = null) {
$indent = str_repeat("\t", $depth); // 缩进
$output .= $indent . '</ul>' . "\n"; // 结束子菜单的 <ul> 标签
}
}
/** --------------------------------------------------------------------------------- *
* 多重筛选 ajax
* --------------------------------------------------------------------------------- */
function dahuzi_filter_posts_ajax() {
// 获取当前页码,默认为1
$paged = isset($_POST['paged']) ? intval($_POST['paged']) : 1;
$tags = isset($_POST['tags']) ? explode(',', sanitize_text_field(implode(',', $_POST['tags']))) : [];
$cats = isset($_POST['cats']) ? array_map('intval', $_POST['cats']) : [];
$args = [
'post_type' => 'post',
'post_status' => 'publish', // 仅查询已发布的文章
'posts_per_page' => 12, // 每页显示12篇文章
'paged' => $paged, // 当前页码
];
//获取当前分类ID 用于获取分类所设置的列表样式
if (isset($_POST['category_id'])) {
$category_id = intval($_POST['category_id']);
}
//分类列表样式
$list_type = get_term_meta($category_id, 'cat_list_type', true);
//根分类
$cat_root_id = get_category_root_id($category_id);
if( !empty( $list_type ) && !empty( $cat_root_id ) ){
$list_type = get_term_meta($cat_root_id, 'cat_list_type', true);
}
//标签匹配规则
$filter_tag = get_term_meta($category_id, 'filter_tag', true);
if( !empty($filter_tag) && !empty($cat_root_id) ){
$filter_tag = get_term_meta($cat_root_id, 'filter_tag', true);
}
//分类匹配规则
$filter_cat = get_term_meta($category_id, 'filter_cat', true);
if( !empty($filter_cat) && !empty($cat_root_id) ){
$filter_cat = get_term_meta($cat_root_id, 'filter_cat', true);
}
//分类+标签 匹配规则
$filter_cat_tag = get_term_meta($category_id, 'filter_cat_tag', true);
if( !empty($filter_cat_tag) && !empty($cat_root_id) ){
$filter_cat_tag = get_term_meta($cat_root_id, 'filter_cat_tag', true);
}
/////////////////////////////////////////
$tax_query = [];
// 如果用户选择了标签,添加标签的 tax_query
if (!empty($tags)) {
$tax_query[] = [
'taxonomy' => 'post_tag',
'field' => 'term_id',
'terms' => $tags,
'operator' => $filter_tag ? $filter_tag : 'IN',
];
}
// 如果用户选择了分类,添加分类的 tax_query
if (!empty($cats)) {
$tax_query[] = [
'taxonomy' => 'category',
'field' => 'id',
'terms' => $cats,
'include_children' => true, //包含子分类的文章
//'operator' => 'IN',
'operator' => $filter_cat ? $filter_cat : 'IN',
];
}
// 如果 tax_query 不为空,则添加到查询参数中
if (!empty($tax_query)) {
$args['tax_query'] = [
//'relation' => 'AND',
'relation' => $filter_cat_tag ? $filter_cat_tag : 'OR', // 根据需要修改关系
...$tax_query // 展开数组,将各项直接放入 tax_query
];
}
// 如果用户没有选择任何标签和分类,返回当前分类的文章
if (empty($tags) && empty($cats)) {
$args['tax_query'] = [
[
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => $category_id, //当前分类ID
'include_children' => true, //包含子分类的文章
],
];
}
/* 已弃用
// 如果用户没有选择任何标签和分类,返回当前分类的文章
if (empty($tags) && empty($cats)) {
$default_category_id = $category_id; // 这里替换为你指定的分类ID
$args['category__in'] = [$default_category_id];
}
*/
// 文章查询
$query = new WP_Query($args);
// 获取符合条件的总文章数量
$total_posts = $query->found_posts;
// 开启输出缓冲,捕获 HTML 输出
ob_start();
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
if (!empty($list_type)) {
$list_type = $list_type;
}else{
$list_type = 'one';
}
get_template_part( 'template/loop/list', $list_type );
}
// 添加分页按钮
$total_pages = $query->max_num_pages;
if ($total_pages > 1) {
echo '<div class="filter-pagination"><ul>';
// Previous Page Link
if ($paged > 1) {
echo '<li class="prev-page"><a href="#" data-page="' . ($paged - 1) . '">'.__('上一页', 'modular_theme').'</a></li>';
}
$range = 2; // 当前页前后显示几页
$ellipsis_shown = false;
for ($i = 1; $i <= $total_pages; $i++) {
if (
$i == 1 || // 首页
$i == $total_pages || // 尾页
($i >= $paged - $range && $i <= $paged + $range) // 当前页附近
) {
if ($i == $paged) {
echo '<li class="active"><span>' . $i . '</span></li>';
} else {
echo '<li><a href="#" data-page="' . $i . '">' . $i . '</a></li>';
}
$ellipsis_shown = false;
} else {
if (!$ellipsis_shown) {
echo '<li><span>···</span></li>';
$ellipsis_shown = true;
}
}
}
// Next Page Link
if ($paged < $total_pages) {
echo '<li class="next-page"><a href="#" data-page="' . ($paged + 1) . '">'.__('下一页', 'modular_theme').'</a></li>';
}
echo '<li><span>' . sprintf(__('共 %d 页', 'modular_theme'), $total_pages) . '</span></li>';
echo '</ul></div>';
}
} else {
echo '<p class="filter-post-no">'.__( '抱歉,没有找到符合条件的文章。', 'modular_theme' ).'</p>';
}
wp_reset_postdata(); //重置查询
// 获取缓冲内容并清除缓冲
$html = ob_get_clean();
// 准备响应数据
$response = [
'html' => $html, // 获取生成的 HTML
'total_posts' => sprintf( __( '查询结果:共找到 %s 条数据', 'modular_theme' ), $total_posts ), // 返回符合条件的总文章数量
];
wp_send_json($response); // 发送 JSON 响应
wp_die(); // 终止执行,返回 AJAX 响应
}
add_action('wp_ajax_dahuzi_filter_posts', 'dahuzi_filter_posts_ajax');
add_action('wp_ajax_nopriv_dahuzi_filter_posts', 'dahuzi_filter_posts_ajax');