You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于WordPress插件动态调整WooCommerce商品列表

解决方案

核心思路

优先使用WooCommerce专属的商品查询钩子,避免影响WordPress全局查询;如果使用通用钩子,必须严格限定修改范围,只针对前台的商品列表查询生效。


推荐方案:使用woocommerce_product_query钩子

这是WooCommerce官方提供的专门用于修改商品查询的钩子,只会作用于商品列表查询,不会干扰其他页面、后台或侧边栏的查询,是最安全的选择。

add_action('woocommerce_product_query', 'filter_products_by_org_pen_setting');
function filter_products_by_org_pen_setting($query) {
    // 跳过后台查询,仅处理前台
    if (is_admin()) return;

    // 替换为你实际获取组织钢笔销售设置的逻辑
    // 示例:从会话中读取用户选择的组织属性(true=仅售钢笔,false=排除钢笔)
    $org_pen_only = isset($_SESSION['selected_org_pen_only']) ? $_SESSION['selected_org_pen_only'] : false;
    $org_exclude_pen = isset($_SESSION['selected_org_exclude_pen']) ? $_SESSION['selected_org_exclude_pen'] : false;
    
    // 无特殊设置时不修改查询
    if (!$org_pen_only && !$org_exclude_pen) return;

    $pen_product_id = 4545; // 替换为你的钢笔商品ID
    // 如果钢笔是多个商品,推荐用分类/标签,示例见下方补充

    if ($org_pen_only) {
        // 仅显示钢笔
        $query->set('post__in', array($pen_product_id));
    } else {
        // 排除钢笔
        $query->set('post__not_in', array($pen_product_id));
    }
}

备选方案:使用pre_get_posts钩子

如果需要用通用WordPress钩子,必须严格限定查询的上下文,确保只修改前台的商品主查询:

add_action('pre_get_posts', 'filter_products_via_pre_get_posts');
function filter_products_via_pre_get_posts($query) {
    // 跳过后台、非主查询、非商品类页面
    if (is_admin() || !$query->is_main_query() || 
        !is_shop() && !is_product_category() && !is_product_tag() && !is_post_type_archive('product')) {
        return;
    }

    // 读取组织钢笔销售设置(同上方示例)
    $org_pen_only = isset($_SESSION['selected_org_pen_only']) ? $_SESSION['selected_org_pen_only'] : false;
    $org_exclude_pen = isset($_SESSION['selected_org_exclude_pen']) ? $_SESSION['selected_org_exclude_pen'] : false;
    
    if (!$org_pen_only && !$org_exclude_pen) return;

    $pen_product_id = 4545;

    if ($org_pen_only) {
        $query->set('post__in', array($pen_product_id));
    } else {
        $query->set('post__not_in', array($pen_product_id));
    }
}

关于posts_where的正确用法

如果一定要用posts_where,必须添加严格的判断条件,只针对商品查询修改WHERE子句,否则会破坏所有WordPress查询:

add_filter('posts_where', 'filter_products_via_posts_where', 10, 2);
function filter_products_via_posts_where($where, $query) {
    // 仅针对前台商品主查询
    if (is_admin() || !$query->is_main_query() || $query->get('post_type') !== 'product') {
        return $where;
    }

    // 读取组织钢笔销售设置(同上方示例)
    $org_pen_only = isset($_SESSION['selected_org_pen_only']) ? $_SESSION['selected_org_pen_only'] : false;
    $org_exclude_pen = isset($_SESSION['selected_org_exclude_pen']) ? $_SESSION['selected_org_exclude_pen'] : false;
    
    if (!$org_pen_only && !$org_exclude_pen) return $where;

    $pen_product_id = 4545;

    if ($org_pen_only) {
        $where .= " AND wp_posts.ID = '$pen_product_id'";
    } else {
        $where .= " AND wp_posts.ID != '$pen_product_id'";
    }

    return $where;
}

补充:多钢笔商品的灵活过滤

如果钢笔是多个商品,建议给这些商品添加统一的分类(如“钢笔”)或标签,然后用tax_query过滤,比单个ID更灵活:

// 仅显示钢笔分类的商品
$query->set('tax_query', array(
    array(
        'taxonomy' => 'product_cat',
        'field'    => 'slug',
        'terms'    => 'pen', // 替换为你的钢笔分类slug
    )
));

// 排除钢笔分类的商品
$query->set('tax_query', array(
    array(
        'taxonomy' => 'product_cat',
        'field'    => 'slug',
        'terms'    => 'pen',
        'operator' => 'NOT IN',
    )
));

内容的提问来源于stack exchange,提问作者lmat - Reinstate Monica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:01:55