HEX
Server: nginx/1.16.1
System: Linux VM-0-14-centos 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec 22 13:25:12 UTC 2021 x86_64
User: www (1000)
PHP: 8.3.31
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
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');