0

I run a blog site with posts by authors, and I implemented a search that would return results if the search was like an author's name or the search term was contained in a story. I was functioning and properly returned authors who matched the search, but now the search returns every user every single time.

I suspect it has something to do with WP_User_query since since that function was updated in 4.2, but I have no idea how I would change it to be compatible.

Here is the search code:

add_filter('user_search_columns', 'user_search_columns_bd' , 10, 3);

function user_search_columns_bd($search_columns, $search, $this){
    if(!in_array('display_name', $search_columns)){
        $search_columns[] = 'display_name';
    }
    return $search_columns;
}

add_filter( 'get_meta_sql', 'user_meta_filter', 10, 6 );

function user_meta_filter( $sql, $queries, $type, $primary_table, $primary_id_column, $context ){
    if ( $type !== 'user' ){
        return $sql;
    }

    if ( ! isset( $context->query_vars['meta_query']['replace_and'] ) || $context->query_vars['meta_query']['replace_and'] !== true ){
        return $sql;
    }

    $sql['where'] = preg_replace('/AND/', 'OR', $sql['where'], 1);
    return $sql;
}   


$args = array(
'search'         => $s,
'search_columns' => array( 'user_login', 'user_email'),
'meta_query' => array(
    'relation' => 'OR',
    'replace_and' => true, 
    array(
        'key'     => 'first_name',
        'value'   => $s,
        'compare' => 'LIKE'
    ),
    array(
        'key'     => 'last_name',
        'value'   => $s,
        'compare' => 'LIKE'
    )
)
);

// The Query
$user_query = new WP_User_Query( $args ); 

1 Answer 1

0

The problem was due to the fact that the query was restructured in this latest update. As pointed out by d79 in this question, the query changed from:

SELECT DISTINCT SQL_CALC_FOUND_ROWS wp_users.* FROM wp_users INNER JOIN wp_usermeta ON ( wp_users.ID = wp_usermeta.user_id )  INNER JOIN wp_usermeta AS mt1 ON ( wp_users.ID = mt1.user_id ) WHERE 1=1 AND (user_login LIKE 'test' OR user_email LIKE 'test' OR display_name LIKE 'test') OR ( 
  ( 
    ( 
      ( wp_usermeta.meta_key = 'first_name' AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%test%' ) 
      OR 
      ( wp_usermeta.meta_key = 'last_name' AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%test%' )
    ) 
    AND 
    mt1.meta_key = 'wp_6_capabilities'
  )
) ORDER BY user_login ASC 

to

SELECT DISTINCT SQL_CALC_FOUND_ROWS wp_users.* FROM wp_users INNER JOIN wp_usermeta ON ( wp_users.ID = wp_usermeta.user_id )  INNER JOIN wp_usermeta AS mt1 ON ( wp_users.ID = mt1.user_id ) WHERE 1=1 OR ( 
  ( 
    ( 
      ( wp_usermeta.meta_key = 'first_name' AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%test%' ) 
      OR 
      ( wp_usermeta.meta_key = 'last_name' AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%test%' )
    ) 
    AND 
    mt1.meta_key = 'wp_6_capabilities'
  )
) AND (user_login LIKE 'test' OR user_email LIKE 'test' OR display_name LIKE 'test') ORDER BY user_login ASC

Therefore, his function:

add_action('pre_user_query', 'my_custom_users_search');

function my_custom_users_search( $args ) {
    if( isset( $args->query_vars['meta_query']['replace_and'] ) && $args->query_vars['meta_query']['replace_and'] )
        $args->query_where = str_replace(') AND (', ') OR (', $args->query_where);
}

targeted the correct AND to be changed to an OR. His solution fixed the problem for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.