web-dev-qa-db-fra.com

WP_User_Query ne combinera pas les méthodes de recherche meta + normales

J'ai essayé de lancer une recherche sur les noms d'utilisateurs en suivant le codex wordpress, mais cela ne semble pas fonctionner ...

La requête suivante, directement copiée à partir du codex, renvoie 0 résultat. Cependant, si je supprime le paramètre meta_query (ou le paramètre 'search', selon que je recherche un nom d'utilisateur ou un prénom), les résultats sont renvoyés. Est-ce un bug avec Wordpress?

Essentiellement, malgré le codex et de nombreux exemples, j'ai explicitement indiqué que 'search' et 'meta_query' peuvent fonctionner ensemble, mais cela ne semble pas être le cas. Quelqu'un peut-il me le confirmer?

$meta_search = 'Ross';

$qArgs = array (
    'order' => 'ASC',
    'orderby' => 'display_name',
    'search' => '*'.esc_attr( $meta_search ).'*',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'first_name',
            'value'   => $meta_search,
            'compare' => 'LIKE'
        ),
        array(
            'key'     => 'last_name',
            'value'   => $meta_search,
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'description',
            'value' => $meta_search ,
            'compare' => 'LIKE'
        )
    )
);

$find_users = new WP_User_Query($qArgs);

Solution: en raison de la fonctionnalité manquante ici, j'ai été obligé d'exécuter 2 requêtes distinctes et de les fusionner. Formulaire lointain idéal mais en temps réel, je ne peux pas attendre une correction de bogue. Donc, pour ce que sa valeur (qui pour les développeurs de plus haut niveau sera minimale, mais pour les intermédiaires sera utile, espérons-le), voici mon travail autour de -

// ORIGINAL QUERY
$qArgs = array('role' => 'subscriber','posts_per_page' => -1);

// SIMPLE SEARCH
$search1Args = array('search' => '*'.esc_attr($meta_search).'*');    
// merge search with original query
$s1Args = array_merge($qArgs, $search1Args);
// go fetch
$find_users_1 = new WP_User_Query($s1Args);

// META QUERY
$search2Args = array(
    'meta_query' => array(
    'relation' => 'OR',
    array(
        'key'     => 'first_name',
        'value'   => $meta_search,
        'compare' => 'LIKE'
    ),
    array(
        'key'     => 'last_name',
        'value'   => $meta_search,
        'compare' => 'LIKE'
    )
    )
);
// merge search with original query
$s2Args = array_merge($qArgs, $search2Args);
// go fetch
$find_users_2 = new WP_User_Query($s2Args);

// MERGE QUERIES
$find_out_1 = $find_users_1->get_results();
$find_out_2 = $find_users_2->get_results();
$found_users = array_merge_recursive($find_out_1, $find_out_2); // rebuild the returned users

$find_count_1 = $find_users_1->total_users;
$find_count_2 = $find_users_2->total_users;
$find_count = ($find_count_1 + $find_count_2); // rebuild the user count

// RECOMPILE
$find_users = $find_users_1;
$find_users->results = $found_users;
$find_users->total_users = $find_count;

En guise d'avertissement, je n'ai pas envisagé la pagination ici et il faudrait envisager si quelqu'un s'attend à l'utiliser sur un site comportant beaucoup d'utilisateurs.

3
Ant

Ils semblent fonctionner ensemble, mais notez la partie AND entre la partiesearchet la requêtemeta query, dans la requête SQL générée. Je me demande si vous attendiez plutôt OR?

Voici les requêtes SQL générées, pour les deux cas que vous avez mentionnés:

Recherche + Meta Query:

SELECT DISTINCT SQL_CALC_FOUND_ROWS wp_users.* 
    FROM wp_users 
    INNER JOIN wp_usermeta 
        ON ( wp_users.ID = wp_usermeta.user_id ) 
    WHERE 1=1 
        AND 
        ( 
            (
                    wp_usermeta.meta_key = 'first_name' 
                AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%Ross%' 
            ) 
            OR 
            ( 
                    wp_usermeta.meta_key = 'last_name' 
                AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%Ross%' 
            ) 
            OR 
            (   
                    wp_usermeta.meta_key = 'description' 
                AND CAST(wp_usermeta.meta_value AS CHAR) LIKE '%Ross%'
            )
        ) 
        AND 
        (
               user_login LIKE '%Ross%' 
            OR user_nicename LIKE '%Ross%'
        ) 
    ORDER BY display_name ASC ;

Seulement rechercher:

SELECT SQL_CALC_FOUND_ROWS wp_users.* 
    FROM wp_users 
    WHERE 1=1 
        AND 
        (
               user_login LIKE '%Ross%' 
            OR user_nicename LIKE '%Ross%'
        ) 
    ORDER BY display_name ASC ;

Vérification de base:

Dans le noyau, nous avons la méthode WP_User_Query::get_search_sql()return an AND part:

return ' AND (' . implode(' OR ', $searches) . ')';

et similairement dans la méthode WP_Meta_Query::get_sql_clauses(), nous avons une partie AND:

$sql['where'] = ' AND ' . $sql['where'];
0
birgire