Hola @ user2041:
Claramente, como sabe, debe modificar la búsqueda que se realiza, lo que puede hacer modificando los valores en la instancia de la WP_User_Search
clase utilizada para la búsqueda (puede encontrar el código fuente en /wp-admin/includes/user.php
si desea estudiarlo).
El WP_User_Search
objeto
Así print_r()
es como se ve un objeto con WordPress 3.0.3 cuando busca el término " TEST
" y sin ningún otro complemento que pueda afectarlo:
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] =>
)
El pre_user_search
gancho
Para modificar los valores del WP_User_Search
objeto, usará el 'pre_user_search'
gancho que recibe la instancia actual del objeto; Llamé print_r()
desde ese gancho para obtener acceso a sus valores que mostré arriba.
El siguiente ejemplo que puede copiar al functions.php
archivo de su tema o puede usar en un archivo PHP para un complemento que está escribiendo agrega la capacidad de buscar en la descripción del usuario además de poder buscar en los otros campos. La función modifica query_from
y las query_where
propiedades del $user_search
objeto que necesita para sentirse cómodo con SQL para comprender.
SQL de modificación cuidadosa en ganchos
El código en la yoursite_pre_user_search()
función asume que ningún otro complemento ha modificado la query_where
cláusula anterior; si otro plugin ha modificado la cláusula where de tal manera que la sustitución 'WHERE 1=1 AND ('
con "WHERE 1=1 AND ({$description_where} OR"
ya no funciona entonces esto va a romper también. Es mucho más difícil escribir una adición robusta que no pueda ser rota por otro complemento al modificar SQL de esta manera, pero es lo que es.
Agregue espacios iniciales y finales al insertar SQL en ganchos
También tenga en cuenta que cuando se utiliza SQL como esto en WordPress, siempre es una buena idea para incluir espacios iniciales y finales como a con " INNER JOIN {$wpdb->usermeta} ON "
lo contrario su consulta SQL podría contener la siguiente donde no hay espacio antes "INNER"
, lo que por supuesto fallar: " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.
Usar en "{$wpdb->table_name"}
lugar de nombres de tabla de codificación fija
A continuación, asegúrese de usar siempre las $wpdb
propiedades para hacer referencia a los nombres de las tablas en caso de que el sitio haya cambiado el prefijo de la tabla 'wp_'
a otra cosa. Por lo tanto, es mejor hacer referencia "{$wpdb->users}.ID"
(con comillas dobles, no simples) en lugar de codificar "wp_users.ID"
.
Limite la consulta a solo cuando existan términos de búsqueda
Por último, modifique la consulta solo cuando haya un término de búsqueda que pueda probar inspeccionando la search_term
propiedad del WP_User_Search
objeto.
La yoursite_pre_user_search()
función para'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 búsqueda de cada par clave-valor meta requiere un SQL JOIN
Por supuesto, la razón probable por la que WordPress no le permite buscar en los campos de datos de usuario es que cada uno agrega un SQL JOIN
a la consulta y, de hecho, una consulta con demasiadas combinaciones puede ser lenta. Si realmente necesita buscar en muchos campos, entonces crearía un '_search_cache'
campo en usermeta que recopila toda la otra información en un campo de usermeta para requerir solo una unión para buscarlo todo.
Los guiones bajos principales en Meta Keys le dicen a WordPress que no se muestre
Tenga en cuenta que el guión bajo destacado '_search_cache'
le dice a WordPress que este es un valor interno y no es algo que nunca se muestre al usuario.
Crear una caché de búsqueda con los 'profile_update'
y 'user_register'
ganchos
Por lo tanto, deberá conectar ambos 'profile_update'
y 'user_register'
eso se activará al guardar un usuario y registrar un nuevo usuario, respectivamente. Puede tomar todas las claves meta y sus valores en esos ganchos (pero omita aquellos con valores que son series serializadas o codificadas en URL) y luego concatenarlas para almacenarlas como un valor meta largo usando la '_search_cache'
clave.
Almacenar Meta como '|'
pares de valor clave delimitados
Decidí tomar todos los nombres clave y todos sus valores y concatenarlos en una gran cadena con dos puntos (":") que separan las claves de los valores y las barras verticales ("|") que separan los pares clave-valor de esta manera (I los he envuelto a través de múltiples líneas para que pueda sin desplazarse hacia la derecha):
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
Permite búsquedas especializadas en Meta usando key:value
Agregar la clave y los valores como lo hicimos le permite realizar búsquedas como " rich_editing:true
" para encontrar a todos los que tienen una edición enriquecida, o buscar " phone:null
" para encontrar aquellos sin número de teléfono.
Pero cuidado con los artefactos de búsqueda
Por supuesto, el uso de esta técnica crea artefactos de búsqueda posiblemente no deseados, como la búsqueda de "negocios", y todos aparecerán en la lista. Si esto es un problema, entonces es posible que no desee utilizar un caché tan elaborado.
La yoursite_profile_update()
función para 'profile_update'
y'user_register'
Para la función yoursite_profile_update()
, como yoursite_pre_user_search()
arriba se puede copiar en el functions.php
archivo de su tema o puede usar en un archivo PHP para un complemento que está escribiendo:
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()
Función actualizada que permite un SQL único JOIN
para buscar todos los metavalores interesantes
Por supuesto, para yoursite_profile_update()
que tenga algún efecto, deberá modificarlo yoursite_pre_user_search()
para usar la '_search_cache'
metaclave en lugar de la descripción, que tenemos aquí (con las mismas advertencias mencionadas anteriormente):
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);
}
}