【问题标题】:WooCommerce Display Purchased Items OnlyWooCommerce 仅显示购买的商品
【发布时间】:2015-02-06 09:11:00
【问题描述】:

所以我在网上搜索了很多,但找不到解决方案...

基本上我要做的是显示用户在商店中购买的所有产品的产品循环,就像显示普通产品一样。

如果你还是不明白,也许这会帮助你明白我的意思..

这是 WooCommerce 文档中的示例产品循环...

<ul class="products">
    <?php
        $args = array(
            'post_type' => 'product',
            'posts_per_page' => 12
            );
        $loop = new WP_Query( $args );
        if ( $loop->have_posts() ) {
            while ( $loop->have_posts() ) : $loop->the_post();
                woocommerce_get_template_part( 'content', 'product' );
            endwhile;
        } else {
            echo __( 'No products found' );
        }
        wp_reset_postdata();
    ?>
</ul><!--/.products-->

如果我想显示基本相同的产品循环,但将其过滤掉,只显示用户已经购买的产品。

老实说,我不知道该去哪里,而且我相信过去有其他人对此进行过研究,所以也许这会帮助很多人!

提前致谢!

【问题讨论】:

    标签: php wordpress woocommerce


    【解决方案1】:

    至少有两种不同的方法可以解决这个问题。

    首先是从每个帖子中获取产品,然后从每个产品中获取产品 ID,然后使用 if 语句使用 wc_customer_bought_product 或 woocommerce_customer_bought_product 进行过滤(如果您使用的是旧版 WooCommerece)。

    第二个是传递正确的参数以过滤 WP_Query 以仅包含用户购买的订单,然后仅过滤这些订单中的产品。有关第二种方法的更多信息,请访问Get All User Orders and Products bought by user in WooCommerce based shop (archive.org)

    第一种方法的示例类似于

    <!-- code started -->
    
    <ul class="products">
        <?php
            $user_id = get_current_user_id();
            $current_user= wp_get_current_user();
            $customer_email = $current_user->email;
            $args = array(
                'post_type' => 'product',
                'posts_per_page' => 12
                );
            $loop = new WP_Query( $args );
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) : $loop->the_post(); $_product = get_product( $loop->post->ID );
                if (wc_customer_bought_product($customer_email, $user_id,$_product->id)){
                    woocommerce_get_template_part( 'content', 'product' );
                }
                endwhile;
            } else {
                echo __( 'No products found' );
            }
            wp_reset_postdata();
        ?>
    </ul><!--/.products-->
    

    【讨论】:

    • 如果我也想只显示某个类别中的产品怎么办?
    • 好吧,我自己想出了类别,但另一个问题是,如果我想让它检查元变量怎么办。例如,如果用户有一个持续订阅,这个持续订阅将在“payment_plan_subscription_id_text_field”下的每个产品元中定义,并且插件即时使用以下函数“woocommerce_members_only(array())”进行检查,那么如果我想说如果客户已购买该产品或 ||如果客户在产品元内的该成员组内。
    • @kmgilbert100 您可以使用给定链接中的代码来实现这一点。请阅读;)
    • fusedpress.com 链接目前已关闭
    【解决方案2】:

    感谢Appleman1234 提供了两个答案,这两个答案都有效。

    ApppleMan1234 提供的第一个示例是遍历所有产品,然后通过调用wc_customer_bought_product() 过滤它们。这肯定会奏效。如果您有n 产品,那么您将进行n+1 数据库查询。

    他的第二个建议是指向 Brajesh Singh 撰写的帖子的链接,该帖子于 2013 年 6 月 2 日在 fusedpress.com 上发布了解决方案。原来的帖子已经没有了。我在谷歌找到了cached copy

    Brajesh Singh 的解决方案先查询用户的订单,然后查询订单详情,最后查询订单商品元数据中的产品 ID。那么这个解决方案总是只有 3 个查询。除非您的商店只有 1 或 2 种产品,否则此解决方案要好得多。

    这是 Brajesh Singh 的代码经过略微编辑的版本。

    /**
     * Get all Products Successfully Ordered by the user
     * @return bool|array false if no products otherwise array of product ids
     */
    function so28362162_get_all_products_ordered_by_user() {
        $orders = so28362162_get_all_user_orders(get_current_user_id(), 'completed');
        if(empty($orders)) {
            return false;
        }
        $order_list = '(' . join(',', $orders) . ')';//let us make a list for query
        //so, we have all the orders made by this user that were completed.
        //we need to find the products in these orders and make sure they are downloadable.
        global $wpdb;
        $query_select_order_items = "SELECT order_item_id as id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id IN {$order_list}";
        $query_select_product_ids = "SELECT meta_value as product_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key=%s AND order_item_id IN ($query_select_order_items)";
        $products = $wpdb->get_col($wpdb->prepare($query_select_product_ids, '_product_id'));
        return $products;
    }
    
    /**
     * Returns all the orders made by the user
     * @param int $user_id
     * @param string $status (completed|processing|canceled|on-hold etc)
     * @return array of order ids
     */
    function so28362162_get_all_user_orders($user_id, $status = 'completed') {
        if(!$user_id) {
            return false;
        }
        $args = array(
            'numberposts' => -1,
            'meta_key' => '_customer_user',
            'meta_value' => $user_id,
            'post_type' => 'shop_order',
            'post_status' => 'publish',
            'tax_query' => array(
                array(
                    'taxonomy' => 'shop_order_status',
                    'field' => 'slug',
                    'terms' => $status
                )
            )
        );
        $posts = get_posts($args);
        //get the post ids as order ids
        return wp_list_pluck($posts, 'ID');
    }
    

    将其与问题中的产品循环相结合,加上未弃用的 wc_get_template_part() 和添加的 posts_per_page=-1 给我们

    <ul class="products">
            <?php
            $args = array(
                'post_type' => 'product',
                'post__in' => so28362162_get_all_products_ordered_by_user(),
                'posts_per_page' => -1
            );
            $loop = new WP_Query($args);
            if($loop->have_posts()) {
                while($loop->have_posts()) : $loop->the_post();
                    wc_get_template_part('content', 'product');
                endwhile;
            }
            else {
                echo __('No products found');
            }
            wp_reset_postdata();
            ?>
        </ul><!--/.products-->
    

    【讨论】:

    • 我担心你的缓存链接也失效了:(谢谢你的解释。我会试试 AppleMan1234 的第二个解决方案(也非常感谢你)。
    【解决方案3】:

    不确定这是否对您有帮助,但 WooThemes 开发了一个 plugin 来支持购买历史记录。

    【讨论】:

    • 我认为原始发帖人要求一个页面向用户显示该用户购买的所有产品,而 WooCommerce 客户历史插件为店主提供后端分析
    猜你喜欢
    • 1970-01-01
    • 2012-01-30
    • 2019-08-16
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 2021-04-20
    相关资源
    最近更新 更多