php - Search Functionality broken by the wp 4.2 update -
repost wordpress.stackexchange:
i run blog site posts authors, , implemented search return results if search author's name or search term contained in story. functioning , returned authors matched search, search returns every user every single time.
i suspect has wp_user_query since
since function updated in 4.2, have no idea how change compatible.
here 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' ) ) ); // query $user_query = new wp_user_query( $args );
edit:
the relevant sql in array form:
array ( [join] => inner join wp_usermeta on ( wp_users.id = wp_usermeta.user_id ) [where] => or ( ( wp_usermeta.meta_key = 'first_name' , cast(wp_usermeta.meta_value char) '%search%' ) or ( wp_usermeta.meta_key = 'last_name' , cast(wp_usermeta.meta_value char) '%search%' ) ) )
i'm not quite sure why sql no longer works in latest update. seems formatted, still returns authors.
it seems right (see comment question): had possibility test query before , after update, , changed:
# before select distinct sql_calc_found_rows wp_users.* wp_users inner join wp_usermeta on ( wp_users.id = wp_usermeta.user_id ) inner join wp_usermeta mt1 on ( wp_users.id = mt1.user_id ) 1=1 , (user_login 'test' or user_email 'test' or display_name 'test') or ( ( ( ( wp_usermeta.meta_key = 'first_name' , cast(wp_usermeta.meta_value char) '%test%' ) or ( wp_usermeta.meta_key = 'last_name' , cast(wp_usermeta.meta_value char) '%test%' ) ) , mt1.meta_key = 'wp_6_capabilities' ) ) order user_login asc # after select distinct sql_calc_found_rows wp_users.* wp_users inner join wp_usermeta on ( wp_users.id = wp_usermeta.user_id ) inner join wp_usermeta mt1 on ( wp_users.id = mt1.user_id ) 1=1 or ( ( ( ( wp_usermeta.meta_key = 'first_name' , cast(wp_usermeta.meta_value char) '%test%' ) or ( wp_usermeta.meta_key = 'last_name' , cast(wp_usermeta.meta_value char) '%test%' ) ) , mt1.meta_key = 'wp_6_capabilities' ) ) , (user_login 'test' or user_email 'test' or display_name 'test') order user_login asc
so line in code
$sql['where'] = preg_replace('/and/', 'or', $sql['where'], 1);
you're changing first and
found in query or
, can see targets wrong one.
in fact condition where 1=1 or ...
, saying always
. :)
so said earlier in comment need target right and
, careful order can change again.
update
unfortunately there's no ultimate way because not native (let's hope it'll added soon), need rely on changing right and
.
maybe find way works both queries (old , new), , need change filter hook: use pre_user_query
:
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(') , (', ') or (', $args->query_where); }
Comments
Post a Comment