【问题标题】:Hide orders that contains a specific product in WooCommmerce "My account" orders table在 WooCommerce“我的帐户”订单表中隐藏包含特定产品的订单
【发布时间】:2021-11-26 11:30:13
【问题描述】:

我的目的是隐藏包含特定产品 ID (5) 的订单。 这在 WooCommmerce“我的帐户”订单表中

我所做的是/myaccount/orders.php中描述的步骤 模板文件。即将文件复制到我的主题文件夹。 (mytheme/woocommerce/myaccount/orders.php.)

我换了

<tbody>
     <?php
     foreach ( $customer_orders->orders as $customer_order ) {
         $order      = wc_get_order( $customer_order ); // phpcs:ignore
WordPress.WP.GlobalVariablesOverride.Prohibited
         $item_count = $order->get_item_count() -
$order->get_item_count_refunded();
         ?>
         <tr class="woocommerce-orders-table__row
woocommerce-orders-table__row--status-<?php echo esc_attr(
$order->get_status() ); ?> order">
         ...
         </tr>
         <?php
     }
     ?>
</tbody>

<tbody>
     <?php
     foreach ( $customer_orders->orders as $customer_order ) {
         $order      = wc_get_order( $customer_order ); // phpcs:ignore
WordPress.WP.GlobalVariablesOverride.Prohibited
         $item_count = $order->get_item_count() -
$order->get_item_count_refunded();

         foreach( $order->get_items() as $item ) {
             $product_id = $item->get_product_id();

             if ( $product_id != 5 ) {
                 ?>
                 <tr class="woocommerce-orders-table__row
woocommerce-orders-table__row--status-<?php echo esc_attr(
$order->get_status() ); ?> order">
                 ...
                 </tr>
                 <?php
             }
         }
     }
     ?>
</tbody>

虽然这没有错误消息,但它不会产生预期的结果。

谁能给点建议?哦,如果有一个解决方案是通过钩子而不是 覆盖模板文件我真的很感激。

【问题讨论】:

标签: wordpress woocommerce product hook-woocommerce orders


【解决方案1】:

如果您查看WC_Order->get_items,这将返回WC_Order_Item 并不总是WC_Order_Item_Product(具有get_product_id)。所以我会尝试这样的事情:

foreach ($customer_orders as $customer_order) {
    $order      = wc_get_order($customer_order); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
    $item_count = $order->get_item_count();

    // Always show orders by default
    $show_order = true;

    // Check if order has specific product ids
    foreach ($order->get_items() as $item) {
        if (is_a($item, 'WC_Order_Item_Product')) {
            $product_id  = $item->get_product_id();
            $product_ids = array(5); // Enter product ids here

            if (in_array($product_id, $product_ids)) {
                // Hide order
                $show_order = false;
            }
        }
    }

    if ($show_order) {
        // <tr>
        // ...
        // </tr>
    }
}

【讨论】:

    【解决方案2】:

    要通过钩子回答您的问题,您可以使用woocommerce_my_account_my_orders_query 过滤钩子。

    下面的代码复制自/includes/wc-template-functions.php line 3159 - 3185 @version 2.5.0

    /**
     * My Account > Orders template.
     *
     * @param int $current_page Current page number.
     */
    function woocommerce_account_orders( $current_page ) {
        $current_page    = empty( $current_page ) ? 1 : absint( $current_page );
        $customer_orders = wc_get_orders(
            apply_filters(
                'woocommerce_my_account_my_orders_query',
                array(
                    'customer' => get_current_user_id(),
                    'page'     => $current_page,
                    'paginate' => true,
                )
            )
        );
    
        wc_get_template(
            'myaccount/orders.php',
            array(
                'current_page'    => absint( $current_page ),
                'customer_orders' => $customer_orders,
                'has_orders'      => 0 < $customer_orders->total,
            )
        );
    }
    

    如您所见,通过钩子,您可以修改wc_get_orders 函数使用的参数。 wc_get_template 函数又使用它。调用/myaccount/orders.php模板文件并传递参数的函数。

    wc_get_orders 允许我们排除 orderID。但没有产品ID。这就是为什么我们要使用一种解决方法,以便我们仍然可以传递必要的 orderID 以作为参数排除。

    获取给定产品ID的所有订单ID的功能,在我的回答中处理是基于Woocommerce: Get all orders for a product回答代码。


    所以要回答你的问题,你会得到:

    function get_orders_ids_by_product_id( $product_id ) {
        global $wpdb;
        
        $statuses = array_keys( wc_get_order_statuses() );
        $statuses = implode( "','", $statuses );
    
        $results = $wpdb->get_col("
            SELECT order_items.order_id
            FROM {$wpdb->prefix}woocommerce_order_items as order_items
            LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
            LEFT JOIN {$wpdb->posts} AS posts ON order_items.order_id = posts.ID
            WHERE posts.post_type = 'shop_order'
            AND posts.post_status IN ('$statuses')
            AND order_items.order_item_type = 'line_item'
            AND order_item_meta.meta_key = '_product_id'
            AND order_item_meta.meta_value = '$product_id'
        ");
    
        return $results;
    }
    
    function filter_woocommerce_my_account_my_orders_query( $args ) {   
        // Get all orders IDs for a given product ID
        $orders_ids = get_orders_ids_by_product_id( 5 );
        
        // Existing args
        $customer = $args['customer'];
        $current_page = $args['page'];
        $paginate = $args['paginate'];
    
        // Get orders that aren't the current order.
        $args = array(
            'customer' => $customer,
            'page'     => $current_page,
            'paginate' => $paginate,
            'exclude'  => $orders_ids,
        );
        
        return $args;
    }
    add_filter( 'woocommerce_my_account_my_orders_query', 'filter_woocommerce_my_account_my_orders_query', 10, 1 );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 2020-11-15
      • 2021-12-07
      • 2021-05-14
      • 2014-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多