wp query – WP Admin Dropdown List Filter for custom (ACF) field on custom post type(s)


I have a custom ACF field of type = user called “visible_to”. This field is set to pull in user_id for all subscriber roles. The admin can select which subscribers a custom post is visible to. For example, add new “resource” custom post type, then choose the user_id the post is visible to. Only that logged in user can see it. (If left blank then all users can see it).

enter image description here

A custom column for this field is already added using the manage_{$post_type}_posts_columns filter. Next I want to add a dropdown list filter for the same field.

enter image description here

My code is based on the closest solution to my problem found here: Filter by custom field in custom post type on admin page

My problem revolves around my lack of understanding $query and parse_query filter. It is two-fold:

  1. The query results are pulling the meta value, as expected, but I need to convert this to user_id as a label that the logged in user can understand. I’m not sure the best way to do this. I previously tried changing my query to return user_id from wp_users but I cannot join wp_users to wp_posts. Plus that did not help with problem 2 below.
    enter image description here
  2. The filter is not currently working. All posts are returned, regardless of the list item selected.

Any help is much appreciated.

My code below.

    add_action('restrict_manage_posts', 'myehs_visible_to_dropdown');
    function myehs_visible_to_dropdown($post_type){
        global $wpdb;

    //Only add dropdown to the appropriate Custom Post Types
        if( $post_type !== 'resource' && $post_type !== 'manual' && $post_type !== 'news')

    //Grab data for the dropdown from the DB
            $query = $wpdb->prepare('
            SELECT DISTINCT pm.meta_value FROM %1$s pm
            LEFT JOIN %2$s p ON p.ID = pm.post_id
            WHERE pm.meta_key = "%3$s" 
            AND p.post_status = "%4$s" 
            AND p.post_type = "%5$s"
            ORDER BY "%3$s"',
            'visible_to', // Meta key
        $results = $wpdb->get_col($query);

    //Ensure there are options to show

    //Get selected option if there is one selected
    if (isset( $_GET['visible'] ) && $_GET['visible'] != '') {
        $selectedName = $_GET['visible'];
    } else {
        $selectedName = -1;

    //Grab all of the options that should be shown
        $options[] = sprintf('<option value="-1">%1$s</option>', __('All Visible To'));
        foreach($results as $result) :
        if ($result == $selectedName) {
        $options[] = sprintf('<option value="%1$s" selected>%2$s</option>', esc_attr($result), $result);
            } else {
                $options[] = sprintf('<option value="%1$s">%2$s</option>', esc_attr($result), $result);

    //Output the dropdown menu
        echo '<select class="" id="visible" name="visible">';
        echo join("n", $options);
        echo '</select>';


    // Make selected dropdown return results
        add_filter( 'parse_query', 'myehs_filter_by_visible_to' );
        function  myehs_filter_by_visible_to($query) {
        global $pagenow;
        $current_page = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
            // If we are in Admin and on the right post type and dropdown selection is made
            if ( is_admin() && 
                $pagenow == 'edit.php' && 
                $current_page == array('resource','manual','news')  && 
                isset( $_GET['visible'] ) && $_GET['visible'] !='' &&
                // Return only posts where visible to matches the selection
                    $query->query_vars['meta_key'] = 'visible_to'; 
                    $query->query_vars['meta_value'] = $_GET['visible'];
                    $query->query_vars['meta_compare'] = '=';

Matthew 1 year 2021-05-15T20:15:32-05:00 0 Answers 0 views 0

Leave an answer