Sort Order Items by “menu order” in WooCommerce order edit pages

倖福魔咒の 提交于 2021-02-07 09:15:58

问题


I use this function to sort Woocommerce order admin items by menu order but But products with variables do not display properly. And if there are several product with variables in the order, only one of them will be displayed.

edit: we have problem with multiple items of a product with different attributes:

item1: product A,variable a,attribute: red color, qty 12

item2: Product A, variable a, attribute: green color, qty 18

after sort it only shows :

item1: product A,variable a,attribute: red color, qty 12

In other words product items with same variation id have problem.

add_filter('woocommerce_order_get_items', 'custom_woocommerce_order_get_items', 10, 2);


function custom_woocommerce_order_get_items($items, $object)
       {
           //no need to reorder if less than 2 products
           if(count($items)   <    2)
               return $items;

       //create a list of products within the order
       $products   =   array();
       foreach($items  as  $key    =>  $item)
           {
               $products[  $item['product_id']   ] =   $key;
           }

       $sorted_items  =   array();

       global $post;

       $args   =   array(
                           'posts_per_page'    =>  -1,
                           'post_type'         =>  'product',
                           'orderby'           =>  'menu_order',
                           'order'             =>  'ASC',
                           'post__in'          =>  array_keys($products)
                           );
       $custom_query   =   new WP_Query($args);
       while($custom_query->have_posts())
           {
               $custom_query->the_post();
               $sorted_items[  $products[$post->ID]    ]   =   $items[ $products[$post->ID]    ];
           }

       //check for any left outside items
       foreach($items  as  $key    =>  $item)
           {
               if(isset($sorted_items[$key]))
                   $sorted_items[  $key   ]    =   $item;
           }

       return $sorted_items;

   }

回答1:


Updated: (to include variations IDs when product it's a variable product)

The main issues in your code is in the query where you need to get the also product_variation post type and also in the first loop where you need to get the variation ID for variable products.

Also this code is outdated for WooCommerce 3+ as Order items are now a WC_Order_Item_Product Object and you need to use the available methods of this class instead.

You don't need the global $post; object as it's already as an argument in the function.

I have revisited all your code:

add_filter( 'woocommerce_order_get_items', 'filter_order_get_items', 10, 2 );
function filter_order_get_items( $items, $order ){

    // no need to reorder if less than 2 items
    if(count($items) < 2) return $items;

    $sorted_items = $products_items_ids = array();

    // Get the array of product/variation IDs with Item IDs within the order
    foreach( $items as $item_id => $item ){
        // Get the product ID (Added WC 3+ compatibility)
        $product_id = method_exists( $item, 'get_product_id' ) ? $item->get_product_id() : $item['product_id'];
        // Get the variation ID (Added WC 3+ compatibility)
        $variation_id = method_exists( $item, 'get_variation_id' ) ? $item->get_variation_id() : $item['variation_id'];
        if( $variation_id > 0 )
            $product_id = $variation_id;
        $products_items_ids[ $product_id ] = $item_id;
    }

    // The WP Query based on the product Ids from this order
    $query = new WP_Query( array(
       'posts_per_page'  =>  -1,
       'post_type'       =>  array( 'product', 'product_variation' ), // <== HERE MISSING
       'orderby'         =>  'menu_order',
       'order'           =>  'ASC',
       'post__in'        =>  array_keys( $products_items_ids ),
    ) );

    // Loop in the Query
    if( $query->have_posts() ){
        while( $query->have_posts() ): $query->the_post();
            // Get the post ID
            $post_id = $query->post->ID;

            // Get the corresponding item ID for the current product ID
            $item_id = $products_items_ids[ $post_id ];

            // Get the new sorted array of items
            $sorted_items[$item_id] = $items[$item_id];
        endwhile;
    }
    wp_reset_query();

    return $sorted_items;
}

Code goes in function.php file of your active child theme (or active theme) or in any plugin file.

Tested and works for all products including product variations on WooCommerce v2.5.x to v3.2+



来源:https://stackoverflow.com/questions/47495141/sort-order-items-by-menu-order-in-woocommerce-order-edit-pages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!