Search code examples
wordpresswordpress-hook

How can I filter records in custom post type list in admin based on user_id that passed as a query string parameter


Is there any option that I can further filter post list for a custom post type in admin based on user_id if the same has been passed as a query string like http://album.multibaselocal.com/wp-admin/edit.php?post_type=albums&user_id=31 ?

Here is what I want to accomplish:

I have a custom post type called album which is used by site users to upload Albums to the system. By default when I go to the list page all albums come up fine. In user list page, I have added a custom column which shows a count of Published albums by each user which links back to album list page with a query string user_id like above.

I want to filter the albums by the user_id I have passed. Is this possible?

I am trying this:

add_filter( 'parse_query', 'filter_albums_further_if_user_id_found');

function filter_albums_further_if_user_id_found($query) {
    if( isset($_GET['user_id']) && !empty($_GET['user_id'])) {
        $user_id = $_GET['user_id'];

        $requery = array(
            'post_type' => 'albums',
            'post_author' => $user_id,
            'status' => 'publish',
            'posts_per_page' => -1,
        );

        // What to do here?
    }
}

I have lost here completely. Not an experienced WP developer!

If I have not understood it all wrong, because the hook I am using is called parse_query, I have to somehow parse the query again and filter the existing result using user_id. But don't know where and how.

EDIT (Query output):

WP_Query Object
(
    [query] => Array
        (
            [post_type] => albums
            [posts_per_page] => 20
        )

    [query_vars] => Array
        (
            [post_type] => albums
            [posts_per_page] => 20
            [error] => 
            [m] => 
            [p] => 0
            [post_parent] => 
            [subpost] => 
            [subpost_id] => 
            [attachment] => 
            [attachment_id] => 0
            [name] => 
            [static] => 
            [pagename] => 
            [page_id] => 0
            [second] => 
            [minute] => 
            [hour] => 
            [day] => 0
            [monthnum] => 0
            [year] => 0
            [w] => 0
            [category_name] => 
            [tag] => 
            [cat] => 
            [tag_id] => 
            [author] => 
            [author_name] => 
            [feed] => 
            [tb] => 
            [paged] => 0
            [meta_key] => user_id
            [meta_value] => 31
            [preview] => 
            [s] => 
            [sentence] => 
            [title] => 
            [fields] => 
            [menu_order] => 
            [embed] => 
            [category__in] => Array
                (
                )

            [category__not_in] => Array
                (
                )

            [category__and] => Array
                (
                )

            [post__in] => Array
                (
                )

            [post__not_in] => Array
                (
                )

            [post_name__in] => Array
                (
                )

            [tag__in] => Array
                (
                )

            [tag__not_in] => Array
                (
                )

            [tag__and] => Array
                (
                )

            [tag_slug__in] => Array
                (
                )

            [tag_slug__and] => Array
                (
                )

            [post_parent__in] => Array
                (
                )

            [post_parent__not_in] => Array
                (
                )

            [author__in] => Array
                (
                )

            [author__not_in] => Array
                (
                )

        )

    [tax_query] => WP_Tax_Query Object
        (
            [queries] => Array
                (
                )

            [relation] => AND
            [table_aliases:protected] => Array
                (
                )

            [queried_terms] => Array
                (
                )

            [primary_table] => 
            [primary_id_column] => 
        )

    [meta_query] => 
    [date_query] => 
    [post_count] => 0
    [current_post] => -1
    [in_the_loop] => 
    [comment_count] => 0
    [current_comment] => -1
    [found_posts] => 0
    [max_num_pages] => 0
    [max_num_comment_pages] => 0
    [is_single] => 
    [is_preview] => 
    [is_page] => 
    [is_archive] => 1
    [is_date] => 
    [is_year] => 
    [is_month] => 
    [is_day] => 
    [is_time] => 
    [is_author] => 
    [is_category] => 
    [is_tag] => 
    [is_tax] => 
    [is_search] => 
    [is_feed] => 
    [is_comment_feed] => 
    [is_trackback] => 
    [is_home] => 
    [is_404] => 
    [is_embed] => 
    [is_paged] => 
    [is_admin] => 1
    [is_attachment] => 
    [is_singular] => 
    [is_robots] => 
    [is_posts_page] => 
    [is_post_type_archive] => 1
    [query_vars_hash:WP_Query:private] => 1c0b485390fc9607d8008a14177bd63d
    [query_vars_changed:WP_Query:private] => 
    [thumbnails_cached] => 
    [stopwords:WP_Query:private] => 
    [compat_fields:WP_Query:private] => Array
        (
            [0] => query_vars_hash
            [1] => query_vars_changed
        )

    [compat_methods:WP_Query:private] => Array
        (
            [0] => init_query_flags
            [1] => parse_tax_query
        )

)

EDIT (Function body presently using):

add_action( 'pre_get_posts', 'filter_albums_further_if_user_id_found');

function filter_albums_further_if_user_id_found($query) {
    if(!is_admin())
        return;

    if( isset($_GET['user_id']) && !empty($_GET['user_id']) ) {
        $user_id = $_GET['user_id'];

        $query->set('meta_key', 'user_id');
        $query->set('meta_value', $user_id);

    }

    echo '<pre>'; print_r($query); echo '</pre>'; die();
}

Solution

  • This reminded me of a similar problem I had a couple weeks ago. I was wanting to adjust the 'orderby' part of the query, but I believe you can accomplish your task with the same action. Try using the 'pre_get_posts' action instead of that filter. I haven't tested this, so let me know if it works!

    CORRECT ANSWER (EDITED after user input):

    function user_id_filter( $query ) {
        if ( ! is_admin() && !$query->is_main_query() )
             return;
    
        if( isset($_GET['user_id']) && !empty($_GET['user_id'])) {
            $user_id = $_GET['user_id'];
            $query->set( 'author', $user_id );
        }
        //Debug if necessary
        //echo '<pre>'; print_r($query); echo '</pre>'; die();
    }
    add_action( 'pre_get_posts', 'user_id_filter', 500000000 );
    

    I used this as a reference. https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts