Xin chào @ user2041:
Rõ ràng như bạn biết bạn cần sửa đổi tìm kiếm đã thực hiện bằng cách sửa đổi các giá trị trong thể hiện của WP_User_Search
lớp được sử dụng cho tìm kiếm (bạn có thể tìm mã nguồn tại /wp-admin/includes/user.php
nếu bạn muốn nghiên cứu về nó.)
các WP_User_Search
đối tượng
Đây là một print_r()
đối tượng trông như thế nào với WordPress 3.0.3 khi tìm kiếm cụm từ " TEST
" và không có bất kỳ plugin nào khác có thể ảnh hưởng đến nó:
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] =>
)
các pre_user_search
Hook
Để sửa đổi các giá trị của WP_User_Search
đối tượng, bạn sẽ sử dụng 'pre_user_search'
hook nhận thể hiện hiện tại của đối tượng; Tôi đã gọi print_r()
từ bên trong cái móc đó để có quyền truy cập vào các giá trị mà tôi đã hiển thị ở trên.
Ví dụ sau mà bạn có thể sao chép vào functions.php
tệp của chủ đề hoặc bạn có thể sử dụng trong tệp PHP cho plugin bạn đang viết thêm khả năng tìm kiếm trên mô tả của người dùng ngoài việc có thể tìm kiếm trên các trường khác. Hàm này sửa đổi query_from
và các query_where
thuộc tính của $user_search
đối tượng mà bạn cần phải thoải mái với SQL để hiểu.
Sửa đổi cẩn thận SQL trong hook
Mã trong yoursite_pre_user_search()
hàm giả định rằng không có plugin nào khác đã sửa đổi query_where
mệnh đề trước nó; nếu một plugin khác đã sửa đổi mệnh đề where sao cho thay thế 'WHERE 1=1 AND ('
bằng "WHERE 1=1 AND ({$description_where} OR"
không còn hoạt động thì điều này cũng sẽ bị hỏng. Việc viết một bổ sung mạnh mẽ không thể bị phá vỡ bởi một plugin khác khi sửa đổi SQL như thế này khó hơn nhiều, nhưng đó là những gì nó được.
Thêm không gian hàng đầu và lưu trữ khi chèn SQL vào móc
Cũng lưu ý rằng khi sử dụng SQL như thế này trong WordPress, luôn luôn nên bao gồm các khoảng trắng ở đầu và cuối như vậy " INNER JOIN {$wpdb->usermeta} ON "
nếu không thì truy vấn SQL của bạn có thể chứa những thứ sau đây không có khoảng trắng trước "INNER"
đó, tất nhiên sẽ thất bại : " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.
Sử dụng "{$wpdb->table_name"}
thay vì tên bảng mã hóa
Tiếp theo hãy chắc chắn luôn luôn sử dụng các $wpdb
thuộc tính để tham chiếu tên bảng trong trường hợp trang web đã thay đổi tiền tố bảng từ 'wp_'
một thứ khác. Vì vậy, tốt hơn là tham khảo "{$wpdb->users}.ID"
(với dấu ngoặc kép, không phải là dấu ngoặc đơn) thay vì mã hóa cứng "wp_users.ID"
.
Giới hạn truy vấn chỉ khi thuật ngữ tìm kiếm tồn tại
Cuối cùng, chỉ sửa đổi truy vấn khi có cụm từ tìm kiếm mà bạn có thể kiểm tra bằng cách kiểm tra search_term
thuộc tính của WP_User_Search
đối tượng.
Các yoursite_pre_user_search()
chức năng cho'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);
}
}
Tìm kiếm mỗi cặp giá trị khóa Meta yêu cầu SQL JOIN
Tất nhiên, lý do có khả năng WordPress không cho phép bạn tìm kiếm trên các trường usermeta là vì mỗi người thêm một SQL JOIN
vào truy vấn và một truy vấn có quá nhiều phép nối thực sự có thể bị chậm. Nếu bạn thực sự cần tìm kiếm trên nhiều lĩnh vực thì tôi sẽ tạo một '_search_cache'
trường trong usermeta thu thập tất cả các thông tin khác vào một trường usermeta để chỉ yêu cầu một người tham gia để tìm kiếm tất cả.
Các dấu gạch dưới hàng đầu trong Meta Keys bảo WordPress không hiển thị
Lưu ý rằng việc gạch dưới hàng đầu trong '_search_cache'
nói với WordPress rằng đây là một giá trị nội bộ và không phải là thứ gì đó sẽ hiển thị cho người dùng.
Tạo Cache tìm kiếm với 'profile_update'
và 'user_register'
móc
Vì vậy, bạn sẽ cần nối cả hai 'profile_update'
và 'user_register'
được kích hoạt để lưu người dùng và đăng ký người dùng mới, tương ứng. Bạn có thể lấy tất cả các khóa meta và giá trị của chúng trong các móc đó (nhưng bỏ qua các khóa có giá trị được tuần tự hóa hoặc mảng được mã hóa URL) và sau đó ghép chúng lại để lưu trữ dưới dạng một giá trị meta dài bằng '_search_cache'
khóa.
Lưu trữ Meta dưới dạng '|'
các cặp giá trị khóa được phân tách
Tôi quyết định lấy tất cả các tên khóa và tất cả các giá trị của chúng và ghép chúng thành một chuỗi lớn bằng dấu hai chấm (":") tách các khóa khỏi các giá trị và các thanh dọc ("|") tách các cặp giá trị khóa như thế này (I Chúng đã quấn chúng trên nhiều dòng để bạn có thể cuộn chúng sang bên phả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
Cho phép tìm kiếm chuyên biệt trên Meta bằng cách sử dụng key:value
Thêm khóa và giá trị như chúng tôi đã làm cho phép bạn thực hiện các tìm kiếm như " rich_editing:true
" để tìm mọi người có chỉnh sửa phong phú hoặc tìm kiếm " phone:null
" để tìm những người không có số điện thoại.
Nhưng hãy coi chừng các tạo phẩm tìm kiếm
Tất nhiên sử dụng kỹ thuật này sẽ tạo ra các tạo phẩm tìm kiếm không mong muốn như tìm kiếm "doanh nghiệp" và mọi người sẽ được liệt kê. Nếu đây là một vấn đề thì bạn có thể không muốn sử dụng bộ đệm phức tạp như vậy.
Các yoursite_profile_update()
chức năng cho 'profile_update'
và'user_register'
Đối với chức năng yoursite_profile_update()
, như yoursite_pre_user_search()
trên có thể được sao chép vào functions.php
tệp chủ đề của bạn hoặc bạn có thể sử dụng trong tệp PHP cho plugin bạn đang viết:
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()
Chức năng được cập nhật cho phép một SQL duy nhất JOIN
để tìm kiếm tất cả các giá trị meta thú vị
Tất nhiên yoursite_profile_update()
để có bất kỳ hiệu ứng nào, bạn sẽ cần sửa đổi yoursite_pre_user_search()
để sử dụng '_search_cache'
khóa meta thay vì mô tả mà chúng tôi có ở đây (với cùng một cảnh báo như đã đề cập ở trên):
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);
}
}