Le formulaire de recherche situé en haut de la liste des utilisateurs dans la zone d'administration (wp-admin/users.php) est limité et ne recherche pas dans tous les champs de méta de l'utilisateur, tels que la bio, les poignées de messagerie instantanée, etc. été capable de trouver un plugin qui peut ajouter cela.
Quelqu'un est-il au courant d'un plugin ou d'une fonction que je pourrais créer qui pourrait étendre cette recherche à toute la date de la base de données _usermeta - idéalement, même des champs supplémentaires créés par un plugin ou une fonction.
Bonjour @ user2041:
Clairement, comme vous le savez, vous devez modifier la recherche effectuée en modifiant les valeurs dans l’instance de la classe WP_User_Search
utilisée pour la recherche (vous pouvez trouver le code source à /wp-admin/includes/user.php
si vous souhaitez étudier it.)
WP_User_Search
Voici à quoi ressemble print_r()
de cet objet avec WordPress 3.0.3 lors de la recherche du terme "TEST
" et sans aucun autre plugin susceptible de 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] =>
)
pre_user_search
Pour modifier les valeurs de l'objet WP_User_Search
, vous utiliserez le hook 'pre_user_search'
qui reçoit l'instance actuelle de l'objet. J'ai appelé print_r()
à partir de ce point d'ancrage pour accéder aux valeurs que j'ai affichées ci-dessus.
L'exemple suivant que vous pouvez copier dans le fichier functions.php
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 dans les autres champs. La fonction modifie les propriétés query_from
et query_where
de l'objet $user_search
que vous devez maîtriser le langage SQL pour comprendre.
Le code de la fonction yoursite_pre_user_search()
suppose qu'aucun autre plug-in n'a modifié la clause query_where
auparavant. si un autre plugin a modifié la clause where, de telle sorte que le remplacement de 'WHERE 1=1 AND ('
par "WHERE 1=1 AND ({$description_where} OR"
ne fonctionne plus, cela se terminera également. Il est beaucoup plus difficile d'écrire un ajout robuste qui ne peut pas être cassé par un autre plugin lors de la modification de SQL de cette façon, mais c'est ce qu'il est.
Notez également que lorsque vous utilisez SQL de la sorte dans WordPress, c’est toujours une bonne idée d’inclure des espaces de début et de fin, par exemple avec " INNER JOIN {$wpdb->usermeta} ON "
, sinon votre requête SQL pourrait contenir les éléments suivants dans lesquels il n’ya pas d’espace avant "INNER"
, ce qui bien sûr échouerait: " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.
"{$wpdb->table_name"}
au lieu de noms de table codés en durEnsuite, veillez à toujours utiliser les propriétés $wpdb
pour référencer les noms de table au cas où le site aurait changé le préfixe de table de 'wp_'
à un autre nom. Il est donc préférable de faire référence à "{$wpdb->users}.ID"
(avec des guillemets doubles, pas des guillemets simples) au lieu de coder en dur "wp_users.ID"
.
Enfin, ne modifiez la requête que lorsqu'il existe un terme de recherche que vous pouvez tester en inspectant la propriété search_term
de l'objet WP_User_Search
.
yoursite_pre_user_search()
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);
}
}
JOIN
Bien sûr, la raison pour laquelle WordPress ne vous permet pas de rechercher des champs usermeta est que chacun ajoute une variable SQL JOIN
à la requête et qu’une requête comportant trop de jointures peut effectivement être lente. Si vous avez vraiment besoin de rechercher dans plusieurs champs, je créerais un champ '_search_cache'
dans usermeta qui rassemble toutes les autres informations dans un seul champ usermeta pour ne nécessiter qu'une seule jointure.
Notez que le tiret de soulignement dans '_search_cache'
indique à WordPress qu'il s'agit d'une valeur interne et non d'un élément à afficher pour l'utilisateur.
'profile_update'
et 'user_register'
Il vous faudra donc relier les deux 'profile_update'
et 'user_register'
qui sont déclenchés lors de la sauvegarde d'un utilisateur et de l'enregistrement d'un nouvel utilisateur, respectivement. Vous pouvez récupérer toutes les clés méta et leurs valeurs dans les crochets (mais omettez celles avec des valeurs sérialisées ou des tableaux codés en URL) puis les concaténer pour les stocker sous la forme d'une méta-valeur longue à l'aide de la clé '_search_cache'
.
'|'
Paires clé-valeur délimitéesJ'ai décidé de saisir tous les noms de clé et toutes leurs valeurs et de les concaténer en une 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 (Je les ai mis sur plusieurs lignes pour pouvoir les faire défiler à 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
key:value
Ajouter la clé et les valeurs comme nous vous avons permis de faire des recherches comme "rich_editing:true
" pour trouver tous ceux qui ont une édition enrichie, ou de chercher "phone:null
" pour trouver ceux qui n’ont pas de numéro de téléphone.
Bien sûr, l'utilisation de cette technique crée des artefacts de recherche éventuellement indésirables, tels que la recherche de "business" et tout le monde sera répertorié. Si cela pose un problème, vous ne voudrez peut-être pas utiliser un cache aussi élaboré.
yoursite_profile_update()
pour 'profile_update'
et 'user_register'
Pour la fonction yoursite_profile_update()
, comme yoursite_pre_user_search()
ci-dessus, vous pouvez le copier dans le fichier functions.php
de votre thème ou vous pouvez l'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 permettant à un seul SQL JOIN
de rechercher toutes les méta-valeurs intéressantesBien sûr, pour que yoursite_profile_update()
ait un effet, vous devrez modifier yoursite_pre_user_search()
pour utiliser la clé méta '_search_cache'
à la place de la description, que nous avons ici (avec les mêmes mises en garde que 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);
}
}
J'ai vraiment apprécié l'approche de Mike Schchel et l'explication détaillée ci-dessus. C'était super utile. Je ne pouvais pas le faire fonctionner pour moi puisque pre_user_search est obsolète et ne fonctionne pas réellement dans 3.2. J'ai juste essayé de le remplacer avec pre_user_query mais cela n'a pas fonctionné non plus. Le problème, c'est qu'il semble que $ user_search-> search_term ne fonctionne plus, alors je viens d'utiliser $ _GET ['s']. J'ai fait du piratage et j'ai pu le faire fonctionner en 3.2. La seule chose que vous devez définir est votre tableau de métadonnées interrogeables.
//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);
}
J'espère que ça aide quelqu'un.
Voici une solution pour la nouvelle version de 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' ] ) . "')";
}
Pour votre information, pour les personnes cherchant sur ce sujet (comment ajuster la requête de recherche du panneau utilisateur) et trouver cette excellente page, WP_User_Search a été déconseillé par WP_User_Query à partir de 3.1: http://codex.wordpress.org/Class_Reference/WP_User_Query .