Cześć @ user2041:
Oczywiście, jak wiadomo, należy zmodyfikować wyszukiwanie, które można wykonać, modyfikując wartości w instancji WP_User_Search
klasy użytej do wyszukiwania (kod źródłowy można znaleźć, /wp-admin/includes/user.php
jeśli chcesz go przestudiować).
WP_User_Search
obiektu
Oto co print_r()
jak wygląda ten obiekt w WordPress 3.0.3 podczas wyszukiwania terminu „ TEST
” i bez innych wtyczek, które mogłyby na niego wpływać:
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
Hook
Aby zmodyfikować wartości WP_User_Search
obiektu, użyjesz 'pre_user_search'
haka, który odbiera bieżącą instancję obiektu; Zadzwoniłem print_r()
z tego haka, aby uzyskać dostęp do jego wartości, które pokazałem powyżej.
Poniższy przykład, który możesz skopiować do functions.php
pliku motywu lub użyć w pliku PHP wtyczki, którą piszesz, dodaje możliwość wyszukiwania według opisu użytkownika a także możliwość wyszukiwania w innych polach. Funkcja modyfikuje query_from
i query_where
właściwości $user_search
obiektu, który należy rozumieć w języku SQL.
Ostrożnie modyfikuj SQL w hakach
Kod w yoursite_pre_user_search()
funkcji zakłada, że żadna inna wtyczka nie zmodyfikowała query_where
klauzuli przed nią; jeśli inna wtyczka zmodyfikowała klauzulę where, zastępując ją'WHERE 1=1 AND ('
ze "WHERE 1=1 AND ({$description_where} OR"
nie działa to będzie złamać zbyt. Znacznie trudniej jest napisać solidny dodatek, który nie może zostać uszkodzony przez inną wtyczkę podczas modyfikowania SQL w ten sposób, ale tak właśnie jest.
Dodaj wiodące i końcowe spacje podczas wstawiania SQL w hakach
Zauważ również, że używając SQL w ten sposób w WordPress, zawsze dobrym pomysłem jest dołączenie spacji wiodących i końcowych, w " INNER JOIN {$wpdb->usermeta} ON "
przeciwnym razie zapytanie SQL może zawierać następujące elementy, w których wcześniej nie było miejsca "INNER"
, co oczywiście nie powiedzie się:" FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.
Posługiwać się "{$wpdb->table_name"}
zamiast na stałe nazw tabel
Następnie pamiętaj, aby zawsze używać $wpdb
właściwości do odwoływania się do nazw tabel, na wypadek gdyby strona zmieniła prefiks tabeli z 'wp_'
czegoś innego. Dlatego lepiej jest odwoływać się do nich "{$wpdb->users}.ID"
(z podwójnymi cudzysłowami, a nie pojedynczymi) zamiast na stałe "wp_users.ID"
.
Ogranicz zapytanie do tylko wtedy, gdy istnieją wyszukiwane hasła
Na koniec należy zmodyfikować zapytanie tylko wtedy, gdy istnieje wyszukiwane hasło, które można przetestować, sprawdzając search_term
właściwość plikuWP_User_Search
obiektu.
yoursite_pre_user_search()
Funkcyjny'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);
}
}
Wyszukiwanie każdej pary meta klucz-wartość wymaga kodu SQL JOIN
Oczywiście prawdopodobnym powodem, dla którego WordPress nie pozwala na wyszukiwanie w polach usermeta, jest to, że każde z nich dodaje JOIN
zapytanie SQL do zapytania, a zapytanie zawierające zbyt wiele połączeń może być naprawdę powolne. Jeśli naprawdę potrzebujesz przeszukiwać wiele pól, utworzę '_search_cache'
pole w usermeta, które zbiera wszystkie inne informacje w jedno pole usermeta, aby wymagać tylko jednego połączenia, aby przeszukać wszystko.
Wiodące podkreślenia w klawiszach meta informują WordPress, aby się nie wyświetlał
Zauważ, że wiodący znak podkreślenia '_search_cache'
informuje WordPress, że jest to wartość wewnętrzna, a nie coś, co można kiedykolwiek wyświetlić użytkownikowi.
Utwórz pamięć podręczną wyszukiwania za pomocą haczyków 'profile_update'
i'user_register'
Więc trzeba się podłączyć zarówno 'profile_update'
i 'user_register'
które są wyzwalane na oszczędność użytkownika i rejestracji nowego użytkownika, odpowiednio. Możesz chwycić wszystkie klucze meta i ich wartości w tych punktach zaczepienia (ale pominąć te z wartościami, które są serializowane lub tablice kodowane w adresach URL), a następnie połączyć je w celu przechowywania jako jednej długiej meta wartości za pomocą '_search_cache'
klucza.
Przechowuj Meta jako '|'
rozdzielane pary klucz-wartość
Postanowiłem pobrać wszystkie nazwy kluczy i wszystkie ich wartości i połączyć je w jeden duży ciąg z dwukropkami („:”) oddzielającymi klucze od wartości i pionowymi słupkami („|”) oddzielającymi takie pary klucz-wartość (I zawinąłem je w wiele wierszy, aby można je było przewijać bez przewijania w prawo):
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
Umożliwia wyszukiwanie specjalistyczne w Meta za pomocą key:value
Dodanie klucza i wartości, tak jak to zrobiliśmy, umożliwia wyszukiwanie takie jak „ rich_editing:true
” w celu znalezienia każdego, kto ma bogatą edycję lub wyszukiwanie „phone:null
”, aby znaleźć osoby bez numeru telefonu.
Ale uważaj na artefakty wyszukiwania
Oczywiście użycie tej techniki tworzy potencjalnie niechciane artefakty wyszukiwania, takie jak wyszukiwanie „firmy” i wszyscy będą na liście. Jeśli jest to problem, możesz nie chcieć używać tak skomplikowanej pamięci podręcznej.
yoursite_profile_update()
Funkcyjny 'profile_update'
i'user_register'
Dla funkcji yoursite_profile_update()
, jak yoursite_pre_user_search()
wyżej, można skopiować do functions.php
pliku motywu lub możesz użyć w pliku PHP wtyczki, którą piszesz:
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);
}
Zaktualizowana yoursite_pre_user_search()
funkcja umożliwiająca pojedynczy SQL JOIN
do wyszukiwania wszystkich interesujących wartości meta
Oczywiście, yoursite_profile_update()
aby uzyskać jakikolwiek efekt, musisz zmodyfikować, yoursite_pre_user_search()
aby używać '_search_cache'
meta klucza zamiast opisu, który mamy tutaj (z tymi samymi zastrzeżeniami, jak wspomniano powyżej):
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);
}
}