你好@user2041:
显然,正如您所知,您需要修改所执行的搜索,您可以通过修改WP_User_Search
用于搜索的类(可以在以下位置找到源代码/wp-admin/includes/user.php
如果你想学习的话。)
TheWP_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文件中为正在编写的插件使用,添加了以下功能search on the user\'s description 除了能够搜索其他字段之外。该函数修改query_from
还有query_where
的属性$user_search
您需要熟悉SQL才能理解的对象。
仔细修改挂钩中的SQLyoursite_pre_user_search()
函数假定没有其他插件修改query_where
之前的条款;如果另一个插件修改了where子句\'WHERE 1=1 AND (\'
具有"WHERE 1=1 AND ({$description_where} OR"
不再工作,那么它也会破裂。在这样修改SQL时,编写一个不能被另一个插件破坏的健壮的添加项要困难得多,但事实就是这样。
在挂钩中插入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
对象
Theyoursite_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);
}
}
搜索每个元键值对需要SQL
JOIN
当然,WordPress不允许您搜索usermeta字段的可能原因是每个字段都添加了一个SQL
JOIN
对于查询和具有太多连接的查询,速度确实会很慢。如果你真的需要搜索很多字段,那么我会创建一个
\'_search_cache\'
usermeta中的字段,它将所有其他信息收集到一个usermeta字段中,只需一个连接即可搜索所有信息。
元键中的前导下划线告诉WordPress不要显示\'_search_cache\'
告诉WordPress这是一个内部值,不能向用户显示。
使用创建搜索缓存\'profile_update\'
和\'user_register\'
挂钩,所以您需要同时挂钩\'profile_update\'
和\'user_register\'
分别在保存用户和注册新用户时触发。您可以获取这些挂钩中的所有元键及其值(但忽略那些具有序列化或URL编码数组的值的元键),然后使用\'_search_cache\'
钥匙
将元存储为\'|\'
带分隔符的键值对
我决定获取所有键名及其所有值,并将它们连接成一个大字符串,用冒号(“:”)将键与值分隔开来,用竖条(“|”)将键值对分隔开来,如下图所示(我将它们包装在多行中,这样您就可以不向右滚动):
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
“找到那些没有电话号码的人。
但是要小心搜索工件,当然,使用这种技术可能会创建不需要的搜索工件,例如搜索“业务”,所有人都会被列出。如果这是一个问题,那么您可能不想使用如此复杂的缓存。
Theyoursite_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()
函数启用单个SQLJOIN
用于搜索所有感兴趣的元数据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);
}
}