How to filter users on admin users page by custom meta field?


The Problem

WP appears to remove the value of my query variable before it gets used to filter the list of users.

My Code

This function adds a custom column to my Users table on /wp-admin/users.php:

function add_course_section_to_user_meta( $columns ) {
    $columns['course_section'] = 'Section';
    return $columns;
add_filter( 'manage_users_columns', 'add_course_section_to_user_meta' );

This function tells WP how to fill values in the column:

function manage_users_course_section( $val, $col, $uid ) {
    if ( 'course_section' === $col )
        return get_the_author_meta( 'course_section', $uid );
add_filter( 'manage_users_custom_column', 'manage_users_course_section' );

This adds a dropdown and Filter button above the Users table:

function add_course_section_filter() {
    echo '<select name="course_section" style="float:none;">';
    echo '<option value="">Course Section...</option>';
    for ( $i = 1; $i <= 3; ++$i ) {
        if ( $i == $_GET[ 'course_section' ] ) {
            echo '<option value="'.$i.'" selected="selected">Section '.$i.'</option>';
        } else {
            echo '<option value="'.$i.'">Section '.$i.'</option>';
    echo '<input id="post-query-submit" type="submit" class="button" value="Filter" name="">';
add_action( 'restrict_manage_users', 'add_course_section_filter' );

This function alters the user query to add my meta_query:

function filter_users_by_course_section( $query ) {
    global $pagenow;

    if ( is_admin() && 
         'users.php' == $pagenow && 
         isset( $_GET[ 'course_section' ] ) && 
         !empty( $_GET[ 'course_section' ] ) 
       ) {
        $section = $_GET[ 'course_section' ];
        $meta_query = array(
                'key'   => 'course_section',
                'value' => $section
        $query->set( 'meta_key', 'course_section' );
        $query->set( 'meta_query', $meta_query );
add_filter( 'pre_get_users', 'filter_users_by_course_section' );

Other Information

It creates my dropdown correctly. When I select a course section and click Filter the page refreshes and course_section shows up in the URL, but it has no value associated with it. If I check the HTTP requests, it shows that it gets submitted with the correct variable value, but then there’s a 302 Redirect that seems to strip out the value I selected.

If I submit the course_section variable by typing it directly into the URL, the filter works as expected.

My code is roughly based on this code from Dave Court.

I also tried whitelisting my query var using this code, but with no luck:

function add_course_section_query_var( $qvars ) {
    $qvars[] = 'course_section';
    return $qvars;
add_filter( 'query_vars', 'add_course_section_query_var' );

I’m using WP 4.4. Any ideas why my filter is not working?

, , , morphatic 8 years 2016-01-03T21:07:23-05:00 0 Answers 115 views 0

Leave an answer