답변:
안녕하세요 @ user2041 :
검색에 WP_User_Search
사용 된 클래스 인스턴스의 값을 수정하여 수행 할 수있는 검색을 수정해야한다는 것을 분명히 알 수 있습니다 ( /wp-admin/includes/user.php
공부하려는 경우 소스 코드를 찾을 수 있음 ).
WP_User_Search
객체다음은 " "print_r()
이라는 단어를 검색 할 때 WordPress 3.0.3에서 해당 오브젝트 중 어떤 모양 이며 다른 플러그인이없는 경우에 해당합니다.TEST
WP_User_Search Object
(
[results] =>
[search_term] => TEST
[page] => 1
[role] =>
[raw_page] =>
[users_per_page] => 50
[first_user] => 0
[last_user] =>
[query_limit] => LIMIT 0, 50
[query_orderby] => ORDER BY user_login
[query_from] => FROM wp_users
[query_where] => WHERE 1=1 AND (user_login LIKE '%TEST%' OR user_nicename LIKE '%TEST%' OR user_email LIKE '%TEST%' OR user_url LIKE '%TEST%' OR display_name LIKE '%TEST%')
[total_users_for_query] => 0
[too_many_total_users] =>
[search_errors] =>
[paging_text] =>
)
pre_user_search
후크WP_User_Search
객체 의 값을 수정하려면 객체 'pre_user_search'
의 현재 인스턴스를받는 후크를 사용 합니다. 위 print_r()
후크에서 호출 하여 위에 표시된 값에 액세스했습니다.
테마 functions.php
파일에 복사 하거나 작성중인 플러그인에 대해 PHP 파일에서 사용할 수있는 다음 예 는 다른 필드를 검색 할 수있을뿐만 아니라 사용자 설명 을 검색 하는 기능을 추가합니다. 이 함수는 이해하기 위해 SQL에 익숙해 져야 하는 오브젝트 query_from
의 query_where
특성을 수정합니다 $user_search
.
yoursite_pre_user_search()
함수 의 코드는 다른 플러그인이 query_where
절 을 수정하지 않았다고 가정 합니다. 다른 플러그인이 where 절을 수정 한 경우 교체하도록 'WHERE 1=1 AND ('
하여 "WHERE 1=1 AND ({$description_where} OR"
더 이상 작품은 다음이도 중단됩니다. 이와 같이 SQL을 수정할 때 다른 플러그인으로 인해 깨지지 않는 강력한 추가 기능을 작성하는 것이 훨씬 어렵지만 이것이 바로 그 기능입니다.
또한 WordPress에서 이와 같은 SQL을 사용할 때 항상 앞뒤 공백을 포함하는 것이 좋습니다. " INNER JOIN {$wpdb->usermeta} ON "
그렇지 않으면 SQL 쿼리에 공백이없는 곳에 다음이 포함될 수 있습니다 . "INNER"
물론 실패 " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
합니다.
"{$wpdb->table_name"}
하드 코딩 테이블 이름 대신 사용다음으로 $wpdb
사이트에서 테이블 접두사를 'wp_'
다른 것으로 변경 한 경우 항상 속성을 사용하여 테이블 이름을 참조하십시오 . 따라서 하드 코딩 대신 "{$wpdb->users}.ID"
(작은 따옴표가 아닌 큰 따옴표 로) 참조하는 것이 좋습니다 "wp_users.ID"
.
마지막으로 개체의 search_term
속성을 검사하여 테스트 할 수있는 검색어가있는 경우에만 쿼리를 수정 해야 WP_User_Search
합니다.
yoursite_pre_user_search()
에 대한 기능'pre_user_search'
add_action('pre_user_search','yoursite_pre_user_search');
function yoursite_pre_user_search($user_search) {
global $wpdb;
if (!is_null($user_search->search_term)) {
$user_search->query_from .= " INNER JOIN {$wpdb->usermeta} ON " .
"{$wpdb->users}.ID={$wpdb->usermeta}.user_id AND " .
"{$wpdb->usermeta}.meta_key='description' ";
$description_where = $wpdb->prepare("{$wpdb->usermeta}.meta_value LIKE '%s'",
"%{$user_search->search_term}%");
$user_search->query_where = str_replace('WHERE 1=1 AND (',
"WHERE 1=1 AND ({$description_where} OR ",$user_search->query_where);
}
}
JOIN
물론 WordPress에서 usermeta 필드를 검색 할 수없는 이유는 각각 JOIN
쿼리에 SQL 을 추가하고 조인이 너무 많은 쿼리는 실제로 느릴 수 있기 때문입니다. 많은 필드를 실제로 검색 해야하는 경우 '_search_cache'
usermeta에서 모든 다른 정보를 하나의 usermeta 필드로 수집하여 모든 검색을 위해 하나의 조인 만 필요로하는 필드를 만듭니다.
밑줄을 선행 '_search_cache'
하면 WordPress에 이것이 내부 값이며 사용자에게 표시 할 것이 아니라는 것을 알려줍니다.
'profile_update'
및 'user_register'
후크를 사용하여 검색 캐시 만들기따라서 사용자를 저장하고 새 사용자를 등록 할 때 트리거되는 'profile_update'
것과 'user_register'
이를 모두 연결해야합니다 . 해당 후크에서 모든 메타 키와 해당 값을 가져 와서 ( 직렬화 된 값 또는 URL 인코딩 배열이있는 값은 생략)'_search_cache'
키를 사용하여 하나의 긴 메타 값으로 저장하도록 연결할 수 있습니다 .
'|'
구분 된 키-값 쌍 으로 메타 저장모든 키 이름과 모든 값을 가져 와서 콜론 ( ":")을 사용하여 키를 값과 세로 막대 ( "|")에서 분리하고 키-값 쌍을 다음과 같이 분리하여 하나의 큰 문자열로 연결하기로 결정했습니다 (I 오른쪽으로 스크롤하지 않고 여러 줄로 줄 바꿈했습니다.)
nickname:mikeschinkel|first_name:mikeschinkel|description:This is my bio|
rich_editing:true|comment_shortcuts:false|admin_color:fresh|use_ssl:null|
wp_user_level:10|last_activity:2010-07-28 01:25:46|screen_layout_dashboard:2|
plugins_last_view:recent|screen_layout_post:2|screen_layout_page:2|
business_name:NewClarity LLC|business_description:WordPress Plugin Consulting|
phone:null|last_name:null|aim:null|yim:null|jabber:null|
people_lists_linkedin_url:null
key:value
키와 값을 추가하면 " rich_editing:true
" 와 같은 검색을 수행 하여 편집 기능이 풍부한 모든 사람을 찾거나 " phone:null
"을 검색하여 전화 번호가없는 사람을 찾을 수 있습니다.
물론이 기술을 사용하면 "비즈니스" 검색과 같은 원치 않는 검색 아티팩트가 생성 될 수 있으며 모든 사람이 나열됩니다. 이것이 문제가되면 정교한 캐시를 사용하지 않을 수 있습니다.
yoursite_profile_update()
에 대한 기능 'profile_update'
및'user_register'
위와 yoursite_profile_update()
같은 기능 yoursite_pre_user_search()
을 위해 테마 functions.php
파일에 복사 하거나 작성중인 플러그인에 대해 PHP 파일에서 사용할 수 있습니다.
add_action('profile_update','yoursite_profile_update');
add_action('user_register','yoursite_profile_update');
function yoursite_profile_update($user_id) {
$metavalues = get_user_metavalues(array($user_id));
$skip_keys = array(
'wp_user-settings-time',
'nav_menu_recently_edited',
'wp_dashboard_quick_press_last_post_id',
);
foreach($metavalues[$user_id] as $index => $meta) {
if (preg_match('#^a:[0-9]+:{.*}$#ms',$meta->meta_value))
unset($metavalues[$index]); // Remove any serialized arrays
else if (preg_match_all('#[^=]+=[^&]\&#',"{$meta->meta_value}&",$m)>0)
unset($metavalues[$index]); // Remove any URL encoded arrays
else if (in_array($meta->meta_key,$skip_keys))
unset($metavalues[$index]); // Skip and uninteresting keys
else if (empty($meta->meta_value)) // Allow searching for empty
$metavalues[$index] = "{$meta->meta_key }:null";
else if ($meta->meta_key!='_search_cache') // Allow searching for everything else
$metavalues[$index] = "{$meta->meta_key }:{$meta->meta_value}";
}
$search_cache = implode('|',$metavalues);
update_user_meta($user_id,'_search_cache',$search_cache);
}
yoursite_pre_user_search()
단일 SQL을 JOIN
사용할 수 있도록 업데이트 된 기능물론 yoursite_profile_update()
어떤 영향을 미치려면 여기에있는 설명 대신 메타 키 yoursite_pre_user_search()
를 사용 하도록 수정 '_search_cache'
해야합니다 (위에서 언급 한 것과 동일한 경고가 있음).
add_action('pre_user_search','yoursite_pre_user_search');
function yoursite_pre_user_search($user_search) {
global $wpdb;
if (!is_null($user_search->search_term)) {
$user_search->query_from .= " INNER JOIN {$wpdb->usermeta} ON " .
"{$wpdb->users}.ID={$wpdb->usermeta}.user_id AND " .
"{$wpdb->usermeta}.meta_key='_search_cache' ";
$meta_where = $wpdb->prepare("{$wpdb->usermeta}.meta_value LIKE '%s'",
"%{$user_search->search_term}%");
$user_search->query_where = str_replace('WHERE 1=1 AND (',
"WHERE 1=1 AND ({$meta_where} OR ",$user_search->query_where);
}
}
MikeSchinkel의 접근 방식과 위의 철저한 설명에 정말 감사했습니다. 이것은 매우 도움이되었습니다. pre_user_search가 더 이상 사용되지 않아 실제로 3.2에서 작동하지 않아서 작동하지 못했습니다. pre_user_query로 전환하려고 시도했지만 작동하지 않았습니다. 문제는 $ user_search-> search_term이 더 이상 작동하지 않아서 $ _GET [ 's']를 사용한 것 같습니다. 나는 약간의 해킹을했고 3.2에서 이것을 작동시킬 수있었습니다. 설정해야 할 유일한 것은 검색 가능한 메타 데이터 배열입니다.
//Searching Meta Data in Admin
add_action('pre_user_query','yoursite_pre_user_search');
function yoursite_pre_user_search($user_search) {
global $wpdb;
if (!isset($_GET['s'])) return;
//Enter Your Meta Fields To Query
$search_array = array("customer_id", "postal_code", "churchorganization_name", "first_name", "last_name");
$user_search->query_from .= " INNER JOIN {$wpdb->usermeta} ON {$wpdb->users}.ID={$wpdb->usermeta}.user_id AND (";
for($i=0;$i<count($search_array);$i++) {
if ($i > 0) $user_search->query_from .= " OR ";
$user_search->query_from .= "{$wpdb->usermeta}.meta_key='" . $search_array[$i] . "'";
}
$user_search->query_from .= ")";
$custom_where = $wpdb->prepare("{$wpdb->usermeta}.meta_value LIKE '%s'", "%" . $_GET['s'] . "%");
$user_search->query_where = str_replace('WHERE 1=1 AND (', "WHERE 1=1 AND ({$custom_where} OR ",$user_search->query_where);
}
이것이 누군가를 돕기를 바랍니다.
참고 로이 주제를 검색하고 (사용자 패널 검색 쿼리를 조정하는 방법) 사람들 이이 훌륭한 페이지를 찾는 경우 WP_User_Query는 3.1에서 http://codex.wordpress.org/Class_Reference/WP_User_Query 에서 더 이상 사용되지 않습니다 .
이것은 모든 사용자 메타 데이터에 와일드 카드 검색을 추가하는 WordPress 4.7.1에서 생각해 낸 것입니다.
add_action( 'pre_user_query', 'ds_pre_user_search' );
function ds_pre_user_search( $query ) {
global $wpdb;
if( empty($_REQUEST['s']) ){return;}
$query->query_from .= ' LEFT JOIN '.$wpdb->usermeta.' ON '.$wpdb->usermeta.'.user_id = '.$wpdb->users.'.ID';
$query->query_where = "WHERE 1=1 AND (user_login LIKE '%".$_REQUEST['s']."%' OR ID = '".$_REQUEST['s']."' OR meta_value LIKE '%".$_REQUEST['s']."%')";
return $query;
}
기본적으로 우리는 사용자 ID에서 users 및 user_meta 테이블을 조인하고 meta_value 열에 대한 검색을 포함하도록 WHERE 절을 다시 작성합니다.
"%".like_escape( $_GET['s'] )."%"
하는 대신. 다른 모든 사용자 제공 데이터도 마찬가지 입니다. 그렇지 않으면 검색 필드가 데이터의 개방형 게이트웨이가됩니다.