Answers:
@ user2041,您好:
如您所知,您显然需要修改执行的搜索,可以通过修改WP_User_Search
用于搜索的类的实例中的值来完成搜索(/wp-admin/includes/user.php
如果您想研究它,可以找到源代码)。
WP_User_Search
对象在print_r()
搜索术语“ TEST
”且没有任何其他可能影响它的插件时,使用WordPress 3.0.3时,该对象的外观如下:
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文件中使用正在编写的插件,这不仅可以搜索其他字段,还可以搜索用户的描述。该函数修改的query_from
和query_where
属性$user_search
您需要熟悉SQL才能理解对象。
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'
对于function 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'
meta键而不是描述(这里有相同的警告)来使用描述:
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);
}
希望这对某人有帮助。
这是最新版本的wordpress的解决方案。
add_action( 'pre_user_query', 'yoursite_pre_user_search' );
function yoursite_pre_user_search( $query ) {
$query->query_where .= "YOUR QUERY '" . str_replace("*", "%", $query->query_vars[ 'search' ] ) . "')";
}
这就是我为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表联接在一起,并重建WHERE子句以在meta_value列上包括搜索。
"%".like_escape( $_GET['s'] )."%"
代替。这同样适用于所有其他用户提供的数据。否则,您的搜索字段将成为数据的开放门户。