สวัสดี@ 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'
hook ที่รับอินสแตนซ์ปัจจุบันของวัตถุ ฉันโทรprint_r()
จากภายในเบ็ดนั้นเพื่อเข้าถึงค่าที่ฉันแสดงด้านบน
ตัวอย่างต่อไปนี้ซึ่งคุณสามารถคัดลอกไปยังfunctions.php
ไฟล์ธีมของคุณหรือคุณสามารถใช้ในไฟล์ PHP สำหรับปลั๊กอินที่คุณกำลังเขียนเพิ่มความสามารถในการค้นหาคำอธิบายของผู้ใช้นอกเหนือจากการค้นหาในฟิลด์อื่น ๆ ฟังก์ชั่นปรับเปลี่ยนquery_from
และquery_where
คุณสมบัติของ$user_search
วัตถุที่คุณต้องคุ้นเคยกับ SQL ที่จะเข้าใจ
การแก้ไข SQL ใน hooks อย่างระมัดระวัง
รหัสในyoursite_pre_user_search()
ฟังก์ชั่นสันนิษฐานว่าไม่มีปลั๊กอินอื่นที่ได้แก้ไขquery_where
อนุประโยคก่อนหน้า หากปลั๊กอินอื่นมีการแก้ไขส่วนคำสั่งที่แทนที่'WHERE 1=1 AND ('
ด้วย"WHERE 1=1 AND ({$description_where} OR"
ไม่ทำงานอีกต่อไปนี้จะแตกเกินไป มันยากกว่ามากในการเขียนส่วนเสริมที่แข็งแกร่งซึ่งไม่สามารถแยกได้โดยปลั๊กอินอื่นเมื่อทำการแก้ไข SQL เช่นนี้ แต่มันคือสิ่งที่มันเป็น
เพิ่มช่องว่างนำหน้าและต่อท้ายเมื่อแทรก SQL ใน Hooks
นอกจากนี้ยังทราบว่าเมื่อใช้ SQL เช่นนี้ใน WordPress ก็มักจะเป็นความคิดที่ดีที่จะรวมชั้นนำและช่องว่างต่อท้ายเช่นมี" INNER JOIN {$wpdb->usermeta} ON "
ตัวเลขที่มิฉะนั้นแบบสอบถาม SQL ของคุณอาจมีดังต่อไปนี้ที่มีพื้นที่ไม่ก่อนที่จะล้มเหลวของหลักสูตร:"INNER"
" FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
ใช้"{$wpdb->table_name"}
แทนชื่อตาราง Hardcoding
ถัดไปอย่าลืมใช้$wpdb
คุณสมบัติเพื่ออ้างอิงชื่อตารางในกรณีที่ไซต์เปลี่ยนคำนำหน้าตารางจาก'wp_'
เป็นอย่างอื่น ดังนั้นมันจะดีกว่าที่จะอ้างถึง"{$wpdb->users}.ID"
(ที่มีราคาคู่ไม่ได้คนเดียว)แทน "wp_users.ID"
hardcoding
จำกัด การค้นหาเฉพาะเมื่อมีคำค้นหาอยู่
สุดท้ายคือปรับเปลี่ยนการสืบค้นเฉพาะเมื่อมีข้อความค้นหาที่คุณสามารถทดสอบได้โดยการตรวจสอบ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);
}
}
การค้นหาคู่คีย์ - ค่า Meta แต่ละคู่ต้องใช้ SQL JOIN
แน่นอนว่าสาเหตุที่ WordPress ไม่อนุญาตให้คุณค้นหาในช่อง usermeta ก็คือแต่ละคนจะเพิ่ม SQL JOIN
ลงในคิวรีและเพื่อให้คิวรีที่มีตัวเชื่อมมากเกินไปนั้นอาจช้าได้อย่างแน่นอน หากคุณต้องการค้นหาในหลาย ๆ ฟิลด์ฉันจะสร้าง'_search_cache'
เขตข้อมูลใน usermeta ที่รวบรวมข้อมูลอื่น ๆ ทั้งหมดลงในช่อง usermeta หนึ่งช่องเพื่อขอให้เข้าร่วมเพียงครั้งเดียวเพื่อค้นหาทุกอย่าง
ขีดเส้นใต้ชั้นนำใน Meta Keys บอกว่า WordPress จะไม่แสดง
โปรดทราบว่าการนำขีดเส้นใต้มา'_search_cache'
บอกกับ WordPress ว่านี่เป็นค่าภายในและไม่ใช่สิ่งที่จะแสดงต่อผู้ใช้
สร้างแคชค้นหาด้วย'profile_update'
และ'user_register'
hooks
ดังนั้นคุณจะต้องขอทั้งสองอย่าง'profile_update'
และ'user_register'
สิ่งนี้จะถูกกระตุ้นให้บันทึกผู้ใช้และลงทะเบียนผู้ใช้ใหม่ตามลำดับ คุณสามารถคว้าเมตาคีย์และค่าทั้งหมดใน hooks เหล่านั้น(แต่ไม่ใช้เมตาที่มีค่าที่ถูกทำให้เป็นลำดับหรือ URL ที่เข้ารหัสแบบอาร์เรย์)จากนั้นทำการเชื่อมต่อเมตาดาต้าเหล่านั้นเพื่อจัดเก็บเป็นเมตาดาต้ายาว'_search_cache'
ๆ
จัดเก็บ Meta เป็น'|'
คู่คีย์ - ค่าที่คั่น
ฉันตัดสินใจที่จะคว้าชื่อคีย์ทั้งหมดและค่าทั้งหมดของพวกเขาและต่อกันเป็นสตริงใหญ่ที่มี colons (":") แยกคีย์ออกจากค่าและแถบแนวตั้ง ("|") คั่นคู่คีย์ - ค่าเช่นนี้(ฉัน มีการห่อหลายบรรทัดเพื่อให้คุณสามารถทำได้โดยไม่ต้องเลื่อนไปทางขวา):
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
เปิดใช้การค้นหาแบบพิเศษเกี่ยวกับการใช้ Meta 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
เพื่อค้นหาค่า Meta ที่น่าสนใจทั้งหมด
แน่นอนว่า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);
}
}