Как выполнить поиск всех пользователей meta из users.php в admin

Форма поиска в верхней части списка пользователей в области администратора (wp-admin / users.php) ограничена и не выполняет поиск по всем мета-полям пользователя, таким как био, ручки обмена мгновенными сообщениями и т. Д. Я не смог найти плагин, который может добавить это.

Кто-нибудь знает о плагине или функции, которую я мог бы создать, которая могла бы расширить этот поиск для всей даты в _usermeta DB – в идеале даже дополнительные поля создаются с помощью плагина или функции.

Solutions Collecting From Web of "Как выполнить поиск всех пользователей meta из users.php в admin"

Привет @ 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' который получает текущий экземпляр объекта; Я вызвал print_r() из этого крюка, чтобы получить доступ к его значениям, которые я отобразил выше.

Следующий пример, который вы можете скопировать в файл functions.php вашей темы или вы можете использовать в файле PHP для плагина, который вы пишете, добавляет возможность поиска по описанию пользователя в дополнение к возможности поиска по другим полям. Функция изменяет query_from и query_where объекта $user_search который вам нужно для понимания SQL.

Тщательное изменение SQL в Крюках

Код в функции yoursite_pre_user_search() предполагает, что ни один другой плагин не изменил предложение query_where до него; если другой плагин изменил предложение where таким образом, что вместо 'WHERE 1=1 AND (' with "WHERE 1=1 AND ({$description_where} OR" больше не работает », это тоже сломается. Гораздо сложнее написать надежное дополнение который не может быть разбит другим плагином при модификации SQL, как это, но это то, что есть.

Добавление ведущих и трейлинг-пространств при вставке SQL в клики

Также обратите внимание, что при использовании SQL в WordPress всегда полезно включать в себя ведущие и конечные пробелы, такие как " INNER JOIN {$wpdb->usermeta} ON " иначе ваш SQL-запрос может содержать следующее, где нет места перед "INNER" , который, конечно же, завершится неудачей: " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON " .

Используйте "{$wpdb->table_name"} вместо имен таблицы жесткого кодирования

Затем обязательно обязательно используйте свойства $wpdb для ссылки на имена таблиц в случае, если сайт изменил префикс таблицы с 'wp_' на что-то еще. Таким образом, лучше обращаться к "{$wpdb->users}.ID" (с двойными кавычками, а не одиночными) вместо hardcoding "wp_users.ID" .

Ограничьте запрос только в тех случаях, когда условия поиска Exist

Наконец, нужно только модифицировать запрос, когда есть термин поиска, который вы можете проверить, search_term свойство 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); } } 

Поиск каждой пары значений мета-ключа требует SQL JOIN

Конечно, вероятная причина, по которой WordPress не позволяет вам искать по полям usermeta, заключается в том, что каждый добавляет SQL JOIN в запрос, а запрос с слишком большим количеством соединений может быть медленным. Если вам действительно нужно искать по многим полям, я бы создал поле «_search_cache» в usermeta, которое собирает всю другую информацию в одно поле usermeta, чтобы требовать только одно соединение для поиска всего.

Ведущие подчеркивания в мета-ключах говорят WordPress не отображать

Обратите внимание, что ведущее подчеркивание в '_search_cache' сообщает WordPress, что это внутреннее значение, а не что-то когда-либо отображаемое пользователю.

Создайте кэш поиска с помощью 'profile_update' и 'user_register' Hooks

Таким образом, вам нужно будет подключить как 'profile_update' и 'user_register' , которые запускаются при сохранении пользователя и регистрации нового пользователя соответственно. Вы можете захватить все мета-ключи и их значения в этих крючках (но опустите те, у которых есть значения, которые являются сериализованными или закодированными по URL-адресам массивами), а затем объединяют их для хранения как одного длинного мета-значения с помощью ключа '_search_cache' .

Хранить Мета как '|' Разделенные пары ключевого значения

Я решил захватить все ключевые имена и все их значения и объединить их в одну большую строку с двоеточиями («:»), отделяющую ключи от значений и вертикальных баров («|»), разделяющих пары значений ключа как это (I 've обернул их через несколько строк, чтобы вы могли их без прокрутки вправо):

 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'

Для функции 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); } не 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); } не 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); } не 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' вместо описания, которое мы имеем здесь (с теми же предостережениями, что упоминалось выше):

 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); } } 

Я очень оценил подход Майка Шинкеля и подробное объяснение выше. Это было очень полезно. Я не мог заставить его работать для меня, так как 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); } 

Надеюсь, это поможет кому-то.

FYI, для людей, которые ищут эту тему (как настроить поисковый запрос панели пользователя) и найти эту отличную страницу, WP_User_Search устарел WP_User_Query по состоянию на 3.1: http://codex.wordpress.org/Class_Reference/WP_User_Query .

Вот решение для новейшей версии 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; }
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; } 

В основном мы просто присоединяем таблицы пользователей и user_meta к идентификатору пользователя и перестраиваем предложение WHERE, чтобы включить поиск в столбец meta_value.