Extending search in backend orders list for product items by id or by sku

Im trying to use the following code from Search by order item SKU or ID in Woocommerce Orders Admin page to enable searching woocommerce orders by sky and id, sku being the important part for me.

   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", $sku);
            add_post_meta($order_id, "_product_id", $product_id);
        }
    }

    return array_merge($search_fields, array('_product_sku', '_product_id'));
});

When I add this to my functions.php I get the following errors:

Read More
Array() expects parameter 1 to be a valid callback, function 'woocommerce_shop_order_search_order_total' not found or invalid function name in /var/sites/s/silverfx.co.uk/public_html/wp-includes/plugin.php on line 235

Warning: array_merge(): Argument #1 is not an array in /var/sites/s/silverfx.co.uk/public_html/wp-content/themes/SilverFx-Theme/functions.php on line 156

Warning: array_map(): Argument #2 should be an array in /var/sites/s/silverfx.co.uk/public_html/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php on line 1533

Warning: array_map(): Argument #2 should be an array in /var/sites/s/silverfx.co.uk/public_html/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php on line 1557

Warning: implode(): Invalid arguments passed in /var/sites/s/silverfx.co.uk/public_html/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php on line 1557

Im making the assumption that since this is about 1 year old and woocommerce have gone through some big changes in that time, this code is needs updating in someway however i am not experienced enough with woocommerce to recognise what is wrong.

If anyonce out there is able to just confirm I am on the correct path or offer guidence / suggestions as to what I might need to do that would be great.

Thanks

Related posts

Leave a Reply

2 comments

  1. Updated: compatibility with WooCommerce 3+

    While woocommerce_shop_order_search_fields filter hook extend search in backend orders list, you need to add some post_meta fields for order item(s) search based on id or sku.

    The author have made a mistake in product sku add_post_meta(). You need to replace undefined $sku variable by $search_sku instead, I think.

    Update: after some thinking and some search around wordpress functions used in this code snippet, I think i have got the solution.

    Here is the updated code related to add_post_meta() function issue:

    add_filter( 'woocommerce_shop_order_search_fields', function ($search_fields ) {
        $orders = get_posts( array( 'post_type' => 'shop_order' ) );
    
        foreach ($orders as $order_post) {
            $order_id = $order_post->ID;
            $order = new WC_Order($order_id);
            $items = $order->get_items();
    
            foreach( $order->get_items() as $item_id => $item_values ) {
                if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
                    $product_id = $item_values['product_id'];
                } else {
                    $product_id = $item_values->get_product_id();
                }
                $search_sku = get_post_meta($product_id, "_sku", true);
                add_post_meta($order_id, "_product_id", $product_id, true); //  <= ## Here ##
                add_post_meta($order_id, "_product_sku", $search_sku, true); // <= ## Here ##
            }
        }
        return array_merge($search_fields, array('_product_id', '_product_sku'));
    } );
    

    There is a missing optional argument, that specify that the value is not an array, when set to true.

    This should work now.

    Reference:

  2. You can do an additinal query in the search result filter. This code will also search the product meta like attributes etc.

    function woocommerce_shop_order_search_results_with_product_info( $order_ids, $term, $search_fields ) {
    global $wpdb;
    
    if ( ! empty( $search_fields ) ) {
        $order_ids = array_unique(
            array_merge(
                $order_ids,
                $wpdb->get_col(
                    $wpdb->prepare(
                        "SELECT DISTINCT order_id
                                FROM kn_woocommerce_order_items
                                RIGHT JOIN (
                                    SELECT kn_woocommerce_order_itemmeta.order_item_id, kn_postmeta.meta_value
                                    FROM kn_woocommerce_order_itemmeta 
                                    LEFT JOIN kn_postmeta ON kn_woocommerce_order_itemmeta.meta_value = kn_postmeta.post_id
                                    WHERE kn_woocommerce_order_itemmeta.meta_key = '_product_id' AND kn_postmeta.meta_value LIKE %s
                                ) AS order_items ON order_items.order_item_id = kn_woocommerce_order_items.order_item_id",
                        '%' . $wpdb->esc_like( wc_clean( $term ) ) . '%'
                    )
                )
            )
        );
    }
    
        return $order_ids; 
    }
    
    add_filter( 'woocommerce_shop_order_search_results', 'woocommerce_shop_order_search_results_with_product_info', 999, 3 );