如何在 WooCommerce 商店页面中自动隐藏用户已购商品

轻芳君_4807

轻芳君_4807

2026-01-11

712人浏览

原创

如何在 WooCommerce 商店页面中自动隐藏用户已购商品

本文介绍如何通过 pre_get_posts 钩子动态过滤 woocommerce 商品列表,使已购买商品对当前登录用户完全不可见,既防止重复购买,又提升 lms 类站点(如 learndash + woocommerce)的课程展示体验。

在构建基于 WooCommerce 的在线学习平台(如 LearnDash 集成场景)时,一个常见且关键的用户体验需求是:当用户已成功购买某门课程(即对应可售商品)后,该商品不应再出现在商店首页(Shop 页面)的商品网格中。这不仅能避免用户误点重复下单,还能让界面更聚焦于“待购课程”,提升导航清晰度与转化效率。

实现这一目标的核心思路是:在 WooCommerce 主商品查询执行前,动态排除当前用户已购商品的 ID 列表。相比仅拦截加购(如 woocommerce_add_to_cart_validation),此方案更彻底——商品从源头上不参与查询、不渲染、不暴露,真正实现“视觉级隐藏”。

以下是推荐使用的完整解决方案,需将代码添加至当前主题的 functions.php 文件中:

add_action( 'pre_get_posts', 'hide_product_from_shop_page_if_user_already_purchased', 20 );

function hide_product_from_shop_page_if_user_already_purchased( $query ) {
    // 仅作用于前台主查询,跳过后台及非主循环
    if ( ! $query->is_main_query() || is_admin() || ! is_shop() ) {
        return;
    }

    $current_user = wp_get_current_user();
    if ( $current_user->ID === 0 ) { // 未登录用户不处理
        return;
    }

    // 查询该用户所有已完成/处理中的订单
    $customer_orders = get_posts( array(
        'posts_per_page' => -1,
        'post_type'      => 'shop_order',
        'post_status'    => array( 'wc-completed', 'wc-processing' ),
        'meta_key'       => '_customer_user',
        'meta_value'     => $current_user->ID,
        'fields'         => 'ids', // 仅获取订单 ID,提升性能
    ) );

    if ( empty( $customer_orders ) ) {
        return;
    }

    $purchased_product_ids = array();

    // 遍历每个订单,提取所购商品 ID(含变体)
    foreach ( $customer_orders as $order_id ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            continue;
        }

        foreach ( $order->get_items() as $item ) {
            $product_id = $item->get_product_id();
            if ( $product_id ) {
                $purchased_product_ids[] = $product_id;
            }
        }
    }

    // 去重并确保为整数数组
    $purchased_product_ids = array_unique( array_map( 'absint', $purchased_product_ids ) );

    if ( ! empty( $purchased_product_ids ) ) {
        $query->set( 'post__not_in', $purchased_product_ids );
    }
}

✅ 关键优化说明:

Contact Form 7 WordPress Form Builder and Mail Integration
Contact Form 7 WordPress Form Builder and Mail Integration

Contact Form 7 是 Rock Lobster Inc. 公司长期运行的 WordPress 表单插件,拥有超过 1000 万次活跃安装,并在 contactform7.com 提供官方文档。此技能适用于需要了解网站表单、邮件模板、验证行为和 shortcode 位置在 Contact Form 7 中实际处理方式的代理。

下载
  • 使用 'fields' => 'ids' 显著减少数据库负载;
  • absint() 确保 ID 安全转为正整数,防范潜在类型异常;
  • 严格限定 is_shop() 和 !is_admin(),避免影响分类页、搜索页或后台管理;
  • 仅对已登录用户生效,游客仍可见全部商品。

⚠️ 注意事项:

  • 此逻辑不影响商品详情页直接访问(如用户通过书签进入)。若需全局拦截,应额外结合 template_redirect 或产品模板内条件判断;
  • 对于变体商品(Variable Product),$item->get_product_id() 返回的是变体 ID(而非父商品 ID),因此变体购买后,仅该变体被隐藏——如需隐藏整个父商品,请改用 $item->get_variation_id() ? $item->get_parent_id() : $product_id;
  • 若使用对象缓存(如 Redis、Memcached),可能需清除相关查询缓存以确保实时性;
  • 建议搭配前端 JS 做二次校验(如禁用已购商品的“加入购物车”按钮),增强健壮性。

该方案简洁、高效、符合 WordPress/WooCommerce 最佳实践,已在 LearnDash + WooCommerce 多项目中稳定运行,是构建专业学习门户不可或缺的用户体验优化环节。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php word redis js 前端 wordpress

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

2023.06.20

5036

8

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.28

1455

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1938

5

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

2023.08.17

10563

11

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

1060

4

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

3204

5

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.14

1689

5

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

2023.09.21

5509

3

js生成随机数方法
js生成随机数方法

JavaScript生成随机数的方法,包括使用Math.random()方法生成指定范围内的随机整数、生成随机字符串和生成随机颜色。根据具体需求,可以选择适合的方法来生成随机数,以实现各种功能 。

2023.09.25

3235

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习