Here I created a function to get all possible meta_values of a certain meta_key. Then I hooked restrict_manage_posts to add the new select field of meta_values to the filter form. Finally I hooked parse_query to add the new filter to the post query.
// Global to be used to stop filter from running on get_posts() in get_meta_values()
$GLOBALS['run_meta_filter_on_query'] = true;
// function to grab all possible meta values of the chosen meta key in this case '_payment_method'
function get_meta_values( $meta_key, $post_type="post" ) {
$GLOBALS['run_meta_filter_on_query'] = false;
$posts = get_posts(
array(
'post_type' => $post_type,
'meta_key' => $meta_key,
'posts_per_page' => -1,
)
);
$GLOBALS['run_meta_filter_on_query'] = true;
$meta_values = array();
foreach( $posts as $post ) {
$meta_values[] = get_post_meta( $post->ID, $meta_key, true );
}
return $meta_values;
}
//Hook the filter options form
add_action('restrict_manage_posts','add_meta_value_to_posts');
function add_meta_value_to_posts(){
// only add filter to shop_order
global $post_type;
if( $post_type == 'shop_order' ) {
// function to grab all possible meta values of the chosen meta key in this case '_payment_method'
$meta_values = get_meta_values('_payment_method', 'shop_order');
// Generate select field from meta values
echo '<select name="_payment_method" id="_payment_method">';
$all_selected = sanitize_text_field($_GET['_payment_method']) == 'all' ? ' selected' : '';
echo '<option value="all"'.$all_selected.'>All</option>';
foreach ( $meta_values as $meta_value ) {
$selected = sanitize_text_field($_GET['_payment_method']) == $meta_value ? ' selected' : '';
echo '<option value="'.$meta_value.'"'.$selected.'>'.$meta_value.'</option>';
}
echo '</select>';
}
}
// Hook parse_query to add new filter parameters
add_action('parse_query','filter_posts_per_meta_value');
function filter_posts_per_meta_value( $query ) {
global $pagenow, $post_type;
// Only add parmeeters if on shop_order and if all is not selected
if( $pagenow == 'edit.php' && $post_type == 'shop_order' && !empty($_GET['_payment_method']) && $_GET['_payment_method'] != 'all' && $GLOBALS['run_meta_filter_on_query'] ) {
$query->query_vars['meta_query'][] = array(
'key' => '_payment_method',
'value' => $_GET['_payment_method'],
'compare' => '=',
);
}
}