Salut @ user2041:
De toute évidence, comme vous le savez, vous devez modifier la recherche effectuée, ce que vous pouvez faire en modifiant les valeurs dans l'instance de la WP_User_Search
classe utilisée pour la recherche (vous pouvez trouver le code source à /wp-admin/includes/user.php
si vous souhaitez l'étudier).
L' WP_User_Search
objet
Voici à quoi ressemble un print_r()
de ces objets avec WordPress 3.0.3 lors de la recherche du terme " TEST
" et sans aucun autre plugin qui pourrait l'affecter:
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] =>
)
Le pre_user_search
crochet
Pour modifier les valeurs de l' WP_User_Search
objet, vous utiliserez le 'pre_user_search'
crochet qui reçoit l'instance actuelle de l'objet; J'ai appelé à print_r()
partir de ce crochet pour accéder à ses valeurs que j'ai affichées ci-dessus.
L'exemple suivant que vous pouvez copier dans le functions.php
fichier de votre thème ou que vous pouvez utiliser dans un fichier PHP pour un plugin que vous écrivez ajoute la possibilité de rechercher sur la description de l'utilisateur en plus de pouvoir rechercher sur les autres champs. La fonction modifie les query_from
et les query_where
propriétés de l' $user_search
objet que vous devez maîtriser avec SQL pour comprendre.
Modification soignée de SQL dans les hooks
Le code de la yoursite_pre_user_search()
fonction suppose qu'aucun autre plugin n'a modifié la query_where
clause avant elle; si un autre plugin a modifié la clause where de telle sorte que le remplacement 'WHERE 1=1 AND ('
par "WHERE 1=1 AND ({$description_where} OR"
ne fonctionne plus, cela cassera également. Il est beaucoup plus difficile d'écrire un ajout robuste qui ne peut pas être rompu par un autre plugin lors de la modification de SQL comme celui-ci, mais c'est ce que c'est.
Ajouter des espaces de début et de fin lors de l'insertion de SQL dans des crochets
A noter également que lors de l' utilisation de SQL comme ça dans WordPress , il est toujours une bonne idée d'inclure les espaces de fuite avec un tel " INNER JOIN {$wpdb->usermeta} ON "
sinon votre requête SQL peut contenir les éléments suivants où il n'y a pas d' espace avant "INNER"
, qui d'échec cours: " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.
Utiliser à la "{$wpdb->table_name"}
place des noms de table de codage en dur
Assurez-vous ensuite de toujours utiliser les $wpdb
propriétés pour référencer les noms de table au cas où le site aurait changé le préfixe de la table 'wp_'
en autre chose. Il est donc préférable de s'y référer "{$wpdb->users}.ID"
(avec des guillemets doubles, pas des guillemets simples) au lieu de coder en dur "wp_users.ID"
.
Limiter la requête uniquement lorsque des termes de recherche existent
Enfin, ne modifiez la requête que s'il existe un terme de recherche que vous pouvez tester en inspectant la search_term
propriété de l' WP_User_Search
objet.
La yoursite_pre_user_search()
fonction pour'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 recherche de chaque paire méta clé-valeur nécessite un SQL JOIN
Bien sûr, la raison probable pour laquelle WordPress ne vous permet pas de rechercher dans les champs usermeta est que chacun ajoute un SQL JOIN
à la requête et qu'une requête avec trop de jointures peut être lente en effet. Si vous avez vraiment besoin de rechercher sur de nombreux champs, je '_search_cache'
créerais un champ dans usermeta qui recueille toutes les autres informations dans un champ usermeta pour ne nécessiter qu'une seule jointure pour tout rechercher.
Les soulignements principaux des méta-clés indiquent à WordPress de ne pas s'afficher
Notez que le soulignement principal '_search_cache'
indique à WordPress qu'il s'agit d'une valeur interne et non de quelque chose à afficher à l'utilisateur.
Créer un cache de recherche avec les crochets 'profile_update'
et'user_register'
Vous devrez donc connecter les deux 'profile_update'
et 'user_register'
qui sont déclenchés lors de l'enregistrement d'un utilisateur et de l'enregistrement d'un nouvel utilisateur, respectivement. Vous pouvez récupérer toutes les méta-clés et leurs valeurs dans ces crochets (mais omettre celles dont les valeurs sont des tableaux sérialisés ou encodés par URL) , puis les concaténer pour les stocker en une seule méta-valeur longue à l'aide de la '_search_cache'
clé.
Stocker la méta en tant que '|'
paires de valeurs-clés délimitées
J'ai décidé de saisir tous les noms de clés et toutes leurs valeurs et de les concaténer en une seule grande chaîne avec des deux-points (":") séparant les clés des valeurs et des barres verticales ("|") séparant les paires clé-valeur comme ceci (I les ai enroulés sur plusieurs lignes pour que vous puissiez les faire défiler vers la droite):
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
Permet des recherches spécialisées sur Meta Using key:value
L'ajout de la clé et des valeurs comme nous l'avons fait vous permet de faire des recherches comme " rich_editing:true
" pour trouver tous ceux qui ont une édition riche, ou rechercher " phone:null
" pour trouver ceux sans numéro de téléphone.
Mais attention aux artefacts de recherche
Bien sûr, l'utilisation de cette technique crée des artefacts de recherche potentiellement indésirables tels que la recherche de "business" et tout le monde sera répertorié. Si c'est un problème, vous ne voudrez peut-être pas utiliser un cache aussi élaboré.
La yoursite_profile_update()
fonction pour 'profile_update'
et'user_register'
Pour la fonction yoursite_profile_update()
, comme yoursite_pre_user_search()
ci-dessus peut être copiée dans le functions.php
fichier de votre thème ou vous pouvez utiliser dans un fichier PHP pour un plugin que vous écrivez:
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()
Fonction mise à jour permettant à un seul SQL JOIN
de rechercher toutes les méta-valeurs intéressantes
Bien sûr, pour yoursite_profile_update()
avoir un effet, vous devrez modifier yoursite_pre_user_search()
pour utiliser la '_search_cache'
touche méta au lieu de la description, que nous avons ici (avec les mêmes mises en garde que celles mentionnées ci-dessus):
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);
}
}