Hai @ user2041:
Jelas Anda tahu bahwa Anda perlu memodifikasi pencarian yang dilakukan yang dapat Anda lakukan dengan memodifikasi nilai-nilai dalam contoh WP_User_Search
kelas yang digunakan untuk pencarian (Anda dapat menemukan kode sumber di/wp-admin/includes/user.php
jika Anda ingin mempelajarinya.)
Itu WP_User_Search
Object
Beginilah bentuk print_r()
objek itu dengan WordPress 3.0.3 saat mencari istilah " TEST
" dan tanpa plugin lain yang mungkin memengaruhinya:
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] =>
)
Itu pre_user_search
Hook
Untuk mengubah nilai WP_User_Search
objek Anda akan menggunakan'pre_user_search'
hook yang menerima instance objek saat ini; Saya menelepon print_r()
dari dalam kait itu untuk mendapatkan akses ke nilai-nilainya yang saya tampilkan di atas.
Contoh berikut yang dapat Anda salin ke functions.php
file tema Anda atau Anda dapat menggunakan file PHP untuk plugin yang Anda tulis menambahkan kemampuan untuk mencari di deskripsi pengguna di samping untuk dapat mencari di bidang lain. Fungsi memodifikasi query_from
dan query_where
properti dari $user_search
objek yang Anda perlu nyaman dengan SQL untuk mengerti.
Hati-hati Memodifikasi SQL di Hooks
Kode dalam yoursite_pre_user_search()
fungsi tersebut mengasumsikan bahwa tidak ada plugin lain yang memodifikasi query_where
klausa sebelumnya; jika plugin lain telah memodifikasi klausa mana yang menggantikan'WHERE 1=1 AND ('
dengan yang "WHERE 1=1 AND ({$description_where} OR"
tidak berfungsi lagi maka ini akan rusak juga. Jauh lebih sulit untuk menulis tambahan yang kuat yang tidak dapat dipecah oleh plugin lain ketika memodifikasi SQL seperti ini, tetapi ini adalah apa adanya.
Tambahkan Leading and Trailing Spaces saat Memasukkan SQL ke Hooks
Perhatikan juga bahwa ketika menggunakan SQL seperti ini di WordPress selalu merupakan ide yang baik untuk menyertakan spasi awal dan akhir seperti itu " INNER JOIN {$wpdb->usermeta} ON "
jika tidak, permintaan SQL Anda mungkin berisi yang berikut di mana tidak ada ruang sebelumnya "INNER"
, yang tentu saja akan gagal:" FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.
Menggunakan "{$wpdb->table_name"}
sebagai ganti Nama Tabel Hardcoding
Selanjutnya pastikan untuk selalu menggunakan $wpdb
properti untuk merujuk nama tabel jika situs telah mengubah awalan tabel dari yang 'wp_'
lain. Jadi lebih baik merujuk "{$wpdb->users}.ID"
(dengan tanda kutip ganda, bukan tanda kutip tunggal) daripada hardcoding "wp_users.ID"
.
Batasi Kueri untuk Hanya Saat Persyaratan Pencarian Ada
Terakhir adalah dengan hanya memodifikasi kueri ketika ada istilah pencarian yang dapat Anda uji dengan memeriksa search_term
properti WP_User_Search
objek.
The yoursite_pre_user_search()
Fungsi untuk'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);
}
}
Mencari Setiap Pasangan Nilai Kunci Meta Memerlukan SQL JOIN
Tentu saja kemungkinan alasan WordPress tidak membiarkan Anda mencari di bidang usermeta adalah karena masing-masing menambahkan SQL JOIN
ke kueri dan ke kueri dengan terlalu banyak gabungan bisa memang lambat. Jika Anda benar-benar perlu mencari di banyak bidang maka saya akan membuat '_search_cache'
bidang di usermeta yang mengumpulkan semua informasi lain ke dalam satu bidang usermeta sehingga hanya perlu satu bergabung untuk mencari semuanya.
Memimpin Garis Bawah di Meta Keys memberi tahu WordPress untuk Tidak Ditampilkan
Perhatikan bahwa memimpin garis bawah di '_search_cache'
memberi tahu WordPress bahwa ini adalah nilai internal dan bukan sesuatu yang pernah ditampilkan kepada pengguna.
Buat Cache Pencarian dengan 'profile_update'
dan 'user_register'
Hooks
Jadi, Anda harus menghubungkan keduanya 'profile_update'
dan 'user_register'
yang dipicu untuk masing-masing menyimpan pengguna dan mendaftarkan pengguna baru. Anda bisa mengambil semua kunci meta dan nilainya di dalam kait tersebut (tetapi mengabaikannya dengan nilai-nilai yang serial atau array yang dikodekan URL) lalu menggabungkannya untuk menyimpan sebagai satu nilai meta panjang menggunakan'_search_cache'
kunci tersebut.
Simpan Meta sebagai '|'
Pasangan Nilai Kunci yang Dibatasi
Saya memutuskan untuk mengambil semua nama kunci dan semua nilainya dan menggabungkannya menjadi satu string besar dengan titik dua (":") memisahkan kunci dari nilai dan bar vertikal ("|") memisahkan pasangan nilai kunci seperti ini (saya telah membungkusnya di beberapa baris sehingga Anda dapat melakukannya tanpa menggulir ke kanan):
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
Aktifkan Pencarian Khusus di Meta Menggunakan key:value
Menambahkan kunci dan nilai seperti yang kami lakukan memungkinkan Anda melakukan pencarian seperti " rich_editing:true
" untuk menemukan semua orang yang memiliki banyak pengeditan, atau mencari " phone:null
" untuk menemukan mereka yang tidak memiliki nomor telepon.
Tapi Waspadalah terhadap Artefak Pencarian
Tentu saja menggunakan teknik ini menciptakan kemungkinan artefak pencarian yang tidak diinginkan seperti pencarian "bisnis" dan semua orang akan terdaftar. Jika ini masalah maka Anda mungkin tidak ingin menggunakan cache yang rumit.
The yoursite_profile_update()
Fungsi untuk 'profile_update'
dan'user_register'
Untuk fungsi yoursite_profile_update()
, seperti di yoursite_pre_user_search()
atas dapat disalin ke functions.php
file tema Anda atau Anda dapat menggunakan file PHP untuk plugin yang Anda tulis:
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()
Fungsi yang Diperbarui memungkinkan SQL Tunggal JOIN
untuk Mencari Semua Nilai Meta yang Menarik
Tentu saja untuk yoursite_profile_update()
mendapatkan efek apa pun, Anda perlu memodifikasi yoursite_pre_user_search()
untuk menggunakan '_search_cache'
kunci meta alih-alih deskripsi, yang kami miliki di sini (dengan peringatan yang sama seperti disebutkan di atas):
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);
}
}
Saya sangat menghargai pendekatan MikeSchinkel dan penjelasan menyeluruh di atas. Ini sangat membantu. Saya tidak dapat mengaktifkannya karena pre_user_search sudah usang dan tidak benar-benar berfungsi di 3.2. Saya mencoba hanya beralih dengan pre_user_query tapi itu tidak berhasil. Masalahnya, tampaknya $ user_search-> search_term tidak berfungsi lagi jadi saya hanya menggunakan $ _GET ['s']. Saya melakukan peretasan dan berhasil menjalankannya di 3.2. Satu-satunya hal yang perlu Anda atur adalah array metadata yang bisa dicari.
Semoga ini bisa membantu seseorang.
sumber
FYI, untuk orang yang mencari di topik ini (bagaimana menyesuaikan permintaan pencarian panel Pengguna) dan menemukan halaman yang sangat baik ini, WP_User_Search telah ditinggalkan oleh WP_User_Query pada 3.1: http://codex.wordpress.org/Class_Reference/WP_User_Query .
sumber
Ini adalah solusi untuk wordpress versi terbaru.
sumber
Inilah yang saya buat untuk WordPress 4.7.1 yang menambahkan pencarian wildcard ke semua data meta pengguna.
Pada dasarnya kami hanya bergabung dengan tabel users dan user_meta pada id pengguna dan membangun kembali klausa WHERE untuk memasukkan pencarian pada kolom meta_value.
sumber
"%".like_escape( $_GET['s'] )."%"
sebaliknya. Hal yang sama berlaku untuk semua data yang disediakan pengguna lain . Lepaskan bidang pencarian Anda menjadi pintu gerbang terbuka ke data Anda.