What I am trying to do is to be able to search by order item SKU or ID in the WooCommerce Orders Admin page.
What I have found/done till now, but with no success is
While @Nikos and @blacksquare 's answers work, new post metas are added to every order on every search. If you have 100 orders and make 10 searches, there will be at least 100*10 = 1000 _product_sku
entries in the wp_postmeta
table. If some orders contain multiple products, there will be even more.
As @blacksquare suggested, add_post_meta
should be called when the order is saved. That said, if the site is small and backend search performance isn't too much of a concern, the following code would 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 calling add_post_meta
when an order is created, extra efforts are needed to create _product_sku
for existing orders, and you have to create the _product_sku
for orders made while the code isn't activated. For simplicity sake, I'd just use the solution suggested above.
p.s. @Nikos 's solution does have one (debatable) advantage - if you change a product's SKU after orders are made, Nikos's solution will find those orders using the new SKU, while the solution above will not. That said, a product's SKU should NOT be changed anyway, and it's debatable whether searching new SKUs should show old orders.