I am trying to create a shipping state filter dropdown on WooCommerce admin orders list
First I have added a custom column for shipping state to admin orders list:
add_filter( 'manage_edit-shop_order_columns', 'custom_shipping_state_column', 100 ); function custom_shipping_state_column( $columns ){ $ordered_columns = array(); foreach( $columns as $key => $column ){ $ordered_columns[$key] = $column; if( 'order_notes' == $key ){ $ordered_columns['order_state'] = __( 'State/Province', 'woocommerce'); } } return $ordered_columns; } add_action( 'manage_shop_order_posts_custom_column' , 'shipping_state_order_list_column', 10, 1 ); function shipping_state_order_list_column( $column ) { global $post; if ( 'order_state' === $column ) { $order = wc_get_order( $post->ID ); echo $order->get_shipping_state(); } }
And here’s my dropdown filter, for shipping state:
add_action('restrict_manage_posts', 'filter_province'); function filter_province(){ global $typenow; global $wpdb; $table = $wpdb->prefix . 'woocommerce_shipping_zone_locations'; $sql = 'SELECT location_code FROM `'. $table . '`'; $location_state = array(); $result = $wpdb->get_results($sql); $location_name = array( 'ABR'=>'ABR:Abra', 'AGN'=>'AGN:Agusan del Norte', 'AGS'=>'AGS:Agusan del Sur', 'AKL'=>'AKL:Aklan', 'ALB'=>'ALB:Albay', 'ANT'=>'ANT:Antique', 'APA'=>'APA:Apayao', 'AUR'=>'AUR:Aurora', 'BAS'=>'BAS:Basilan', 'BAN'=>'BAN:Bataan', 'BTN'=>'BTN:Batanes', 'BTG'=>'BTG:Batangas', 'BEN'=>'BEN:Benguet', 'BIL'=>'BIL:Bilaran', 'BOH'=>'BOH:Bohol', 'BUK'=>'BUK:Bukidnon', 'BUL'=>'BUL:Bulacan', 'CAG'=>'CAG:Cagayan', 'CAN'=>'CAN:Camarines Norte', 'CAS'=>'CAS:Camarines Sur', 'CAM'=>'CAM:Camiguin', 'CAP'=>'CAP:Capiz', 'CAT'=>'CAT:Catanduanez', 'CAV'=>'CAV:Cavite', 'CEB'=>'CEB:Cebu', 'COM'=>'COM:Compostela Valley', 'NCO'=>'NCO:Cotobato', 'DAV'=>'DAV:Davao del Norte', 'DAS'=>'DAS:Davao del Sur', 'DAC'=>'DAC:Davao Occidental', 'DAO'=>'DAO:Davao Oriental', 'DIN'=>'DIN:Dinangat Island', 'EAS'=>'EAS:Eastern Samar', 'GUI'=>'GUI:Guimaras', 'IFU'=>'IFU:Ifugao', 'ILN'=>'ILN:Ilocos Norte', 'ILS'=>'ILS:Ilocos Sur', 'ILI'=>'ILI:Iloilo', 'ISA'=>'ISA:Isabela', 'KAL'=>'KAL:Kalinga', 'LUN'=>'LUN:La Union', 'LAG'=>'LAG:Laguna', 'LAN'=>'LAN:Lanao del Norte', 'LAS'=>'LAS:Lanao del Sur', 'LEY'=>'LEY:Leyte', 'MAG'=>'MAG:Maguindanao', 'MAD'=>'MAD:Marinduque', 'MAS'=>'MAS:Masbate', 'MSC'=>'MSC:Misamis Occidental', 'MSR'=>'MSR:Misamis Oriental', 'MOU'=>'MOU:Mountain Province', 'NEC'=>'NEC:Negros Occidental', 'NER'=>'NER:Negros Oriental', 'NSA'=>'NSA:Nothern Samar', 'NUE'=>'NUE:Nueva Ecija', 'NUV'=>'NUV:Nueva Vizcaya', 'MDC'=>'MDC:Occidental Mindoro', 'MDR'=>'MDR:Oriental Mindoro', 'PLW'=>'PLW:Palawan', 'PAM'=>'PAM:Pampanga', 'PAN'=>'PAN:Pangasinan', 'QUE'=>'QUE:Quezon', 'QUI'=>'QUI:Quirino', 'RIZ'=>'RIZ:Rizal', 'ROM'=>'ROM:Romblon', 'WSA'=>'WSA:Samar', 'SAR'=>'SAR:Sarangani', 'SIQ'=>'SIQ:Siquijor', 'SOR'=>'SOR:Sorsogon', 'SCO'=>'SCO:South Cotobato', 'SLE'=>'SLE:Southern Leyte', 'SUK'=>'SUK:Sultan Kudarat', 'SLU'=>'SLU:Sulu', 'SUN'=>'SUN:Surigao del Norte', 'SUR'=>'SUR:Surigao del Sur', 'TAR'=>'TAR:Tarlac', 'TAW'=>'TAW:Tawi-Tawi', 'ZWB'=>'ZWB:Zambales', 'ZAN'=>'ZAN:Zamboanga del Norte', 'ZAS'=>'ZAS:Zamboanga del Sur', 'ZSI'=>'ZSI:Zamboanga Sibugay', '00'=>'00:Metro Manila' ); $getCount = count($location_name); $location = array_values($location_name); // if post type is shop_order if ($typenow=='shop_order') { //check if our select has been sent and if so, is it set to "Currently Due" if (isset($_GET["get_province"])){ $get_province = $_GET["get_province"]; $selected = $get_province; } else { $selected = ""; } echo "<select id='get_province' name='get_province'>"; echo "<option value='' ".selected("", $selected )." >".__( 'State/Province', 'woocommerce' )."</option>"; foreach($result as $res) { $data = explode(':',$res->location_code); for($i=0;$i<$getCount;$i++){ $location_state = explode(':',$location[$i]); if($location_state[0] == $data[1]){ echo "<option value= ".$data[1]." ".selected($data[1], $selected ).">".$location_state[1]."</option>"; } } } echo "</select>"; } }
And here’s my question: How to process the selected filter on admin orders list when I click the filter button?
Advertisement
Answer
There are some mistakes, complications and missing things in your code.
The following will display a functional dropdown filter based on the shipping state location on admin order list (based on shipping settings allowed countries/states):
// Utility function to get all available shipping zones locations function get_wc_shipping_zones_locations( ){ global $wpdb; return $wpdb->get_col(" SELECT DISTINCT location_code FROM {$wpdb->prefix}woocommerce_shipping_zone_locations "); } // Add a dropdown to filter orders by state add_action('restrict_manage_posts', 'add_shop_order_filter_by_state'); function add_shop_order_filter_by_state(){ global $pagenow, $typenow; if( 'shop_order' === $typenow && 'edit.php' === $pagenow ) { // Get available countries codes with their states code/name pairs $country_states = WC()->countries->get_allowed_country_states(); // Initializing $filter_id = 'shipping_state'; $current = isset($_GET[$filter_id])? $_GET[$filter_id] : ''; echo '<select name="'.$filter_id.'"> <option value="">'.__( 'Filter by State/Province', 'woocommerce' )."</option>"; // Loop through shipping zones locations array foreach( get_wc_shipping_zones_locations() as $country_state ) { $country_state = explode(':', $country_state); $country_code = reset($country_state); $state_code = end($country_state); if ( isset( $country_states[$country_code][$state_code] ) && $state_name = $country_states[$country_code][$state_code] ) { printf( '<option value="%s"%s>%s</option>', $state_code, $state_code === $current ? '" selected="selected"' : '', $state_name ); } } echo '</select>'; } } // Process the filter dropdown for orders by shipping state add_filter( 'request', 'process_admin_shop_order_filtering_by_state', 99 ); function process_admin_shop_order_filtering_by_state( $vars ) { global $pagenow, $typenow; $filter_id = 'shipping_state'; if ( $pagenow == 'edit.php' && 'shop_order' === $typenow && isset( $_GET[$filter_id] ) && ! empty($_GET[$filter_id]) ) { $vars['meta_key'] = '_shipping_state'; $vars['meta_value'] = $_GET[$filter_id]; $vars['orderby'] = 'meta_value'; } return $vars; }
Then I have made some little changes to your shipping state custom column in admin orders list:
add_filter( 'manage_edit-shop_order_columns', 'custom_shipping_state_column', 100 ); function custom_shipping_state_column( $columns ){ $sorted_columns = array(); foreach( $columns as $key => $column ){ $sorted_columns[$key] = $column; if( 'order_notes' == $key ){ $sorted_columns['order_state'] = __( 'State/Province', 'woocommerce'); } } return $sorted_columns; } add_action( 'manage_shop_order_posts_custom_column' , 'shipping_state_order_list_column', 10, 1 ); function shipping_state_order_list_column( $column ) { global $post, $the_order; if ( 'order_state' === $column && $shipping_state = $the_order->get_shipping_state() ) { echo $shipping_state; } }
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
Related answer: Filter orders by product post type in WooCommerce admin orders list page