Search by order number or identifier on the WooCommerce order administration page

I am trying to search by order number or item ID on the WooCommerce order administration page.

What I have found / done so far, but to no avail, is in the functions.php file.

 add_filter( 'woocommerce_shop_order_search_fields', 'woocommerce_shop_order_search_sku' ); function woocommerce_shop_order_search_sku( $search_fields ) { $args = array( 'post_type' => 'shop_order' ); $orders = new WP_Query( $args ); if ( $orders->have_posts() ) { while( $orders->have_posts() ) { $post = $orders->the_post(); $order_id = get_the_ID(); $order = new WC_Order( $order_id ); $items = $order->get_items(); foreach( $items as $item ) { $search_order_item_sku = wp_get_post_terms( $item['product_id'], 'search_sku' ); foreach( $search_order_item_sku as $search_sku ) { add_post_meta( $order_id, "_search_sku", $search_sku->sku ); } } } }; $search_fields[] = '_search_sku'; return $search_fields; } 

I assume the problem is the value of $search_sku in the line with add_post_meta .

I also tried this with get_sku() , $item['sku'] without any luck.

+8
php search woocommerce skus orders
source share
4 answers

@blacksquare, @jibby, @helgatheviking, you are men! This is the code that works because of your help.

  //Search by product SKU in Admin Woocommerce Orders add_filter( 'woocommerce_shop_order_search_fields', function ($search_fields ) { $posts = get_posts(array('post_type' => 'shop_order')); foreach ($posts as $post) { $order_id = $post->ID; $order = new WC_Order($order_id); $items = $order->get_items(); foreach($items as $item) { $product_id = $item['product_id']; $search_sku = get_post_meta($product_id, "_sku", true); add_post_meta($order_id, "_product_sku", $search_sku); } } return array_merge($search_fields, array('_product_sku')); }); 
+1
source share

You have the right idea to save additional metadata in an order. As jbby and helgatheviking suggestions show, the built-in postmeta for product_id or sku is available by default in woocommerce api orders. However, your methodology for accessing and saving metadata was not entirely correct. wp_get_post_terms will gain access to user taxonomy information, not metadata (use get_post_meta for this). You can do what you tried to do with this filter:

 add_filter( 'woocommerce_shop_order_search_fields', function ($search_fields ) { $posts = get_posts(array('post_type' => 'shop_order')); foreach ($posts as $post) { $order_id = $post->ID; $order = new WC_Order($order_id); $items = $order->get_items(); foreach($items as $item) { $product_id = $item['product_id']; $search_sku = get_post_meta($product_id, "_sku", true); add_post_meta($order_id, "_product_sku", $search_sku); add_post_meta($order_id, "_product_id", $product_id); } } return array_merge($search_fields, array('_product_sku', '_product_id')); }); 

Strictly speaking, you probably should move calls to add_post_meta to the hook that starts when the order is initially stored in the database - this will prevent unnecessary footwork in every search in order.

+2
source share

While @Nikos and @blacksquare replies work, new message metadata is added to every order for every search. If you have 100 orders and 10 searches are being performed, the wp_postmeta table will have at least 100 * 10 = 1000 _product_sku entries. If some orders contain several products, there will be even more.

As @blacksquare suggested, add_post_meta should be called when the order is saved. However, if the site is small and the backend search performance is not too important, the following code will work without creating redundant _product_sku entries.

 add_filter( 'woocommerce_shop_order_search_fields', 'my_shop_order_search_fields') ); public function my_shop_order_search_fields( $search_fields ) { $orders = get_posts( array( 'post_type' => 'shop_order', 'post_status' => wc_get_order_statuses(), //get all available order statuses in an array 'posts_per_page' => 999999, // query all orders 'meta_query' => array( array( 'key' => '_product_sku', 'compare' => 'NOT EXISTS' ) ) // only query orders without '_product_sku' postmeta ) ); foreach ($orders as $order) { $order_id = $order->ID; $wc_order = new WC_Order($order_id); $items = $wc_order->get_items(); foreach($items as $item) { $product_id = $item['product_id']; $search_sku = get_post_meta($product_id, '_sku', true); add_post_meta( $order_id, '_product_sku', $search_sku ); } } return array_merge($search_fields, array('_product_sku')); // make '_product_sku' one of the meta keys we are going to search for. } 

While a better solution might be to call add_post_meta when creating an order, extra effort is needed to create _product_sku for existing orders, and you must create _product_sku for orders _product_sku until the code is activated. For simplicity, I would just use the solution proposed above.

ps @Nikos solution has one (controversial) advantage - if you change the SKU product after orders are made, Nikos decision to find those orders using the new SKU, while the above solution will not be. However, the SKU product should not be changed in any way, and it is debatable whether the search for new products should show old orders.

+1
source share

You can also watch https://uk.wordpress.org/plugins/woo-search-order-by-sku/ , which does not overload the post-meta, but modifies the where clause.

0
source share

All Articles