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

10,034

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+

Share:
10,034
Amir rajaei zadeh
Author by

Amir rajaei zadeh

Updated on June 28, 2022

Comments

  • Amir rajaei zadeh
    Amir rajaei zadeh almost 2 years

    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;
    
       }
    
  • Amir rajaei zadeh
    Amir rajaei zadeh over 6 years
    we still have problem with multiple items of a product with different attributes: product A,variable a,attribute: red color, qty 12 Product A, variable a, attribute: green color, qty 18 after sort it only shows : product A,variable a,attribute: red color, qty 12 thank you @loictheaztec
  • Amir rajaei zadeh
    Amir rajaei zadeh over 6 years
    please test and order with two items of one product of one variable of two attributes like color(item1: red item 2: green). sorry for my poor english.
  • LoicTheAztec
    LoicTheAztec over 6 years
    @Amirrajaeizadeh Ok see the problem… I have updated my code and this time is working perfecly
  • Amir rajaei zadeh
    Amir rajaei zadeh over 6 years
    Unfortunately, we still have problems with the order of a product in two colors(one variable). see docs.woocommerce.com/wp-content/uploads/2013/05/… @loictheaztec
  • LoicTheAztec
    LoicTheAztec over 6 years
    For me it's working for multiple variations of a variable product too, just as you pointed: see: i.stack.imgur.com/koQEE.png … I have paste back the code that I have and that is working for me, so try it again please
  • Amir rajaei zadeh
    Amir rajaei zadeh over 6 years
    Thank you, it works just with items with different variation id. When two items have same variation id only shows one of them. Please order a variable product with one variation that select all color. (A variable with "any color" value) @loictheaztec
  • LoicTheAztec
    LoicTheAztec over 6 years
    @Amirrajaeizadeh in WooCommerce if you add 2 times the same variation to cart, it just increase the quantity. So in WC Orders you don't have 2 times the same variation ID as 2 separated order items… This can only happen with product custom fields and if it's the case you should have mentioned it in your question…
  • Amir rajaei zadeh
    Amir rajaei zadeh over 6 years
    Variation is same, attribute is different . I will back soon
  • LoicTheAztec
    LoicTheAztec over 6 years
    Is better you contact me on skype chat, my ID is marsloic … When I set a product variation with any / any it's not enable for add to cart… So how you get that as an order item?
  • Amir rajaei zadeh
    Amir rajaei zadeh over 6 years
  • Amir rajaei zadeh
    Amir rajaei zadeh over 6 years
    Did you get a result? @loictheaztec
  • LoicTheAztec
    LoicTheAztec over 6 years
    @Amirrajaeizadeh No I can't get this work for your specific case… I even don't know how you do that…