I am new to WooCommerce, And I want to customize admin order list page. So basically I created new product type. Now I also made restriction that customer can purchase my custom product type’s product or simple product type’s product at a time.
Now in admin order listing page, I want to show order which has simple product type’s product. How I can do this?
I searched a lot, I found an plugin which has filter to show order by product not product type. While studying that plugin I got to know that may be I can do this using posts_where
action. But I don’t have proper idea.
Advertisement
Answer
The following functions will add an additional filter dropdown to admin order list, allowing you to filter orders based on order items product post type:
add_action( 'restrict_manage_posts', 'admin_shop_order_by_product_type_filter' ); function admin_shop_order_by_product_type_filter(){ global $pagenow, $post_type; if( 'shop_order' === $post_type && 'edit.php' === $pagenow ) { $domain = 'woocommerce'; $filter_id = 'filter_product_type'; $current = isset($_GET[$filter_id])? $_GET[$filter_id] : ''; $query_args = ['taxonomy' => 'product_type', 'fields' => 'names', 'orderby' => 'order']; echo '<select name="'.$filter_id.'"> <option value="">' . __('Filter by Product post type', $domain) . '</option>'; foreach ( get_terms($query_args) as $term_name ) { printf( '<option value="%s"%s>%s</option>', $term_name, $term_name === $current ? '" selected="selected"' : '', ucfirst($term_name) ); } echo '</select>'; } } add_action( 'pre_get_posts', 'process_admin_shop_order_product_type_filter' ); function process_admin_shop_order_product_type_filter( $query ) { global $pagenow, $post_type, $wpdb; $filter_id = 'filter_product_type'; if ( $query->is_admin && 'edit.php' === $pagenow && 'shop_order' === $post_type && isset( $_GET[$filter_id] ) && $_GET[$filter_id] != '' ) { $order_ids = $wpdb->get_col( " SELECT DISTINCT o.ID FROM {$wpdb->prefix}posts o INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_id = o.ID INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id INNER JOIN {$wpdb->prefix}term_relationships tr ON oim.meta_value = tr.object_id INNER JOIN {$wpdb->prefix}term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN {$wpdb->prefix}terms t ON tt.term_id = t.term_id WHERE o.post_type = '$post_type' AND oim.meta_key = '_product_id' AND tt.taxonomy = 'product_type' AND t.name = '{$_GET[$filter_id]}' "); $query->set( 'post__in', $order_ids ); // Set the new "meta query" $query->set( 'posts_per_page', 25 ); // Set "posts per page" $query->set( 'paged', ( get_query_var('paged') ? get_query_var('paged') : 1 ) ); // Set "paged" } }
Code goes in functions.php file of your active child theme (or active theme). Tested and work.