Ciao @ user2041:
Chiaramente, come sapete, è necessario modificare la ricerca eseguita, che è possibile fare modificando i valori nell'istanza della WP_User_Search
classe utilizzata per la ricerca (è possibile trovare il codice sorgente /wp-admin/includes/user.php
se si desidera studiarlo.)
L' WP_User_Search
oggetto
Ecco print_r()
come appare uno di quegli oggetti con WordPress 3.0.3 quando si cerca il termine " TEST
" e senza altri plugin che potrebbero influenzarlo:
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] =>
)
The pre_user_search
Hook
Per modificare i valori WP_User_Search
dell'oggetto utilizzerai l' 'pre_user_search'
hook che riceve l'istanza corrente dell'oggetto; Ho chiamato print_r()
da quel gancio per ottenere l'accesso ai suoi valori che ho visualizzato sopra.
Il seguente esempio che puoi copiare nel functions.php
file del tuo tema o che puoi utilizzare in un file PHP per un plugin che stai scrivendo aggiunge la possibilità di cercare nella descrizione dell'utente oltre a poter cercare negli altri campi. La funzione modifica le query_from
e le query_where
proprietà $user_search
dell'oggetto che devi comprendere con SQL per capire.
Attenta modifica di SQL in Hooks
Il codice nella yoursite_pre_user_search()
funzione presuppone che nessun altro plugin abbia modificato la query_where
clausola prima di essa; se un altro plugin ha modificato la clausola where in modo che la sostituzione 'WHERE 1=1 AND ('
con "WHERE 1=1 AND ({$description_where} OR"
non funzioni più, anche questo si interromperà. È molto più difficile scrivere un'aggiunta solida che non può essere interrotta da un altro plugin quando si modifica SQL in questo modo, ma è quello che è.
Aggiungi spazi iniziali e finali quando inserisci SQL negli hook
Si noti inoltre che quando si utilizza SQL come questo in WordPress è sempre una buona idea includere spazi iniziali e finali, quali una con " INNER JOIN {$wpdb->usermeta} ON "
altrimenti la query SQL potrebbe contenere il seguente dove non c'è spazio prima "INNER"
, che naturalmente non riuscire: " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.
Utilizzare al "{$wpdb->table_name"}
posto dei nomi tabella hardcoding
Quindi assicurati di utilizzare sempre le $wpdb
proprietà per fare riferimento ai nomi delle tabelle nel caso in cui il sito abbia modificato il prefisso della tabella da 'wp_'
qualcos'altro. Quindi è meglio fare riferimento "{$wpdb->users}.ID"
(con virgolette doppie, non singole) invece di hardcoding "wp_users.ID"
.
Limitare la query a Solo quando esistono i termini di ricerca
Infine, modificare la query solo quando esiste un termine di ricerca che è possibile verificare controllando la search_term
proprietà WP_User_Search
dell'oggetto.
La yoursite_pre_user_search()
funzione per'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);
}
}
La ricerca di ogni coppia Meta-valore chiave richiede un SQL JOIN
Naturalmente il probabile motivo per cui WordPress non ti consente di cercare nei campi usermeta è che ognuno aggiunge un SQL JOIN
alla query e una query con troppi join può essere effettivamente lenta. Se hai davvero bisogno di cercare in molti campi, '_search_cache'
creerei un campo in usermeta che raccoglie tutte le altre informazioni in un campo usermeta per richiedere un solo join per cercare tutto.
I caratteri di sottolineatura principali in Meta Keys indicano a WordPress di non visualizzare
Si noti che il carattere di sottolineatura iniziale in '_search_cache'
dice a WordPress che questo è un valore interno e non qualcosa da mostrare all'utente.
Creare una cache di ricerca con i hook 'profile_update'
e'user_register'
Quindi dovrai agganciare entrambi 'profile_update'
e 'user_register'
che sono attivati sul salvataggio di un utente e sulla registrazione di un nuovo utente, rispettivamente. Puoi prendere tutte le meta-chiavi e i loro valori in quegli hook (ma omettere quelle con valori che sono array serializzati o con codifica URL) e quindi concatenarle per archiviarle come un lungo meta-valore usando la '_search_cache'
chiave.
Memorizza Meta come '|'
coppie chiave-valore delimitate
Ho deciso di prendere tutti i nomi delle chiavi e tutti i loro valori e concatenarli in un'unica grande stringa con due punti (":") che separano le chiavi dai valori e dalle barre verticali ("|") che separano le coppie chiave-valore in questo modo (I li hai avvolti su più righe in modo da poterli scorrere senza scorrere verso destra):
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
Abilita ricerche specializzate su Meta Using key:value
L'aggiunta della chiave e dei valori, come abbiamo fatto, ti consente di effettuare ricerche come " rich_editing:true
" per trovare tutti coloro che hanno modifiche avanzate o cercare " phone:null
" per trovare quelle senza numero di telefono.
Ma attenzione agli artefatti di ricerca
Naturalmente l'uso di questa tecnica crea artefatti di ricerca potenzialmente indesiderati come la ricerca di "affari" e tutti saranno elencati. Se questo è un problema, potresti non voler utilizzare una cache così elaborata.
La yoursite_profile_update()
funzione per 'profile_update'
e'user_register'
Per funzione yoursite_profile_update()
, come yoursite_pre_user_search()
sopra può essere copiato nel functions.php
file del tuo tema oppure puoi usarlo in un file PHP per un plugin che stai scrivendo:
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()
Funzione aggiornata che abilita un singolo SQL JOIN
per la ricerca di tutti i meta valori interessanti
Ovviamente per yoursite_profile_update()
avere qualche effetto dovrai modificare yoursite_pre_user_search()
per usare la '_search_cache'
meta chiave invece della descrizione, che abbiamo qui (con gli stessi avvertimenti di cui sopra):
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);
}
}