前言
在 WordPress 中,預設的使用者搜尋功能僅能查詢固定欄位如使用者名稱或電子郵件,無法搜尋自定義欄位資料。當網站需要透過電話號碼等自定義欄位進行搜尋時,預設功能就顯得不足。本篇筆記將示範如何利用 WordPress 的鉤子擴充後台使用者搜尋功能,支援自定義欄位的搜尋。
為什麼需要自訂使用者搜尋?
WordPress 預設不支援透過自定義欄位搜尋使用者資料,對於擁有大量自定義欄位的網站管理者來說,這是一大限制。透過自訂搜尋功能,可以讓管理者在後台使用者列表中,直接搜尋像是「reg_phone」這類的自定義欄位,提升管理效率。
自訂使用者搜尋的程式碼範例
以下程式碼示範如何使用 pre_user_query 動作鉤子,修改後台使用者查詢的 SQL,加入對自定義欄位 reg_phone 的搜尋支援:
add_action('pre_user_query', 'project_pre_user_search');
function project_pre_user_search($query) {
global $wpdb;
global $pagenow;
// 僅在後台使用者列表頁且有搜尋字串時執行
if (is_admin() && 'users.php' === $pagenow && !empty($_REQUEST['s'])) {
// 過濾搜尋字串,避免 SQL 注入
$search_term = esc_sql($_REQUEST['s']);
// 加入 DISTINCT 避免重複
$query->query_fields = 'DISTINCT ' . $query->query_fields;
// 連接 usermeta 表以搜尋自定義欄位
$query->query_from .= " LEFT JOIN {$wpdb->usermeta} ON {$wpdb->usermeta}.user_id = {$wpdb->users}.ID";
// 新增搜尋條件,模糊比對 reg_phone 欄位
$query->query_where .= $wpdb->prepare(
" OR ({$wpdb->usermeta}.meta_key = 'reg_phone' AND {$wpdb->usermeta}.meta_value LIKE %s)",
'%' . $search_term . '%'
);
}
return $query;
}
程式碼解說
- 動作鉤子(Action Hook):使用
pre_user_query在查詢執行前修改 SQL。 - 後台頁面檢查:確保只在後台使用者列表頁(users.php)執行。
- 搜尋關鍵字過濾:用
esc_sql()避免 SQL 注入風險。 - 連接使用者欄位表:透過 LEFT JOIN 連接
usermeta表。 - 新增搜尋條件:在 WHERE 子句加入對
reg_phone欄位的模糊搜尋。
如何使用這段程式碼?
- 將程式碼加入主題的
functions.php或自訂外掛中。 - 確認已有名為
reg_phone的自定義使用者欄位,且欄位中有可搜尋資料。 - 進入 WordPress 後台「使用者」頁面。
- 在搜尋框輸入關鍵字,即可搜尋
reg_phone欄位的匹配資料。
此功能的優點
- 靈活性:支援搜尋非預設欄位的自定義資料。
- 安全性:使用 WordPress 原生函數處理輸入,降低風險。
- 可擴展性:可依需求修改支援更多自定義欄位。
完整程式碼
add_action('pre_user_query', 'project_pre_user_search');
function project_pre_user_search($query) {
global $wpdb;
global $pagenow;
if (is_admin() && 'users.php' === $pagenow && !empty($_REQUEST['s'])) {
$search_term = esc_sql($_REQUEST['s']);
$query->query_fields = 'DISTINCT ' . $query->query_fields;
$query->query_from .= " LEFT JOIN {$wpdb->usermeta} ON {$wpdb->usermeta}.user_id = {$wpdb->users}.ID";
$query->query_where .= $wpdb->prepare(
" OR ({$wpdb->usermeta}.meta_key = 'reg_phone' AND {$wpdb->usermeta}.meta_value LIKE %s)",
'%' . $search_term . '%'
);
}
return $query;
}