web-dev-qa-db-fra.com

WP La requête utilisateur échoue lors de la recherche de méta-requêtes et de colonnes de recherche

Je suis en train de créer une recherche utilisateur avancée à l'aide de WP_User_Query, mais je rencontre un comportement inhabituel. J'essaie de chercher avec un terme qui, à ma connaissance, existe dans les champs user_nicename et user_email mais ne retourne pas lorsque j'inclus meta_query dans les $ args.

À l'aide de la requête simple ci-dessous, lors de la recherche dans les données de la table des utilisateurs, WordPress renvoie tout comme prévu, car le terme existe dans les noms d'utilisateur et de messagerie.

$args = array (
    'fields' => ['ID'],
    'count_total' => true,
    'order' => 'ASC',   
    'orderby' => 'display_name',
    'search' => '*'.esc_attr( $search_term ).'*',
);
$wp_user_query = new WP_User_Query($args);

Cependant, lorsque j'introduis une méta_query dans la recherche pour la comparer à la méta de l'utilisateur, la requête ne renvoie aucun résultat, même si les données correspondantes correspondent auparavant à l'aide de la simple instruction. La meta_query donne les arguments $ args comme ceci:

$args = array (
    'fields' => ['ID'],
    'count_total' => true,
    'order' => 'ASC',   
    'orderby' => 'display_name',
    'search' => '*'.esc_attr( $search_term ).'*',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'first_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
        ),
        array(
            'key'     => 'last_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'description',
            'value' => $search_term ,
            'compare' => 'LIKE'
        )
    )
);
$wp_user_query = new WP_User_Query($args);

Je détermine quelles colonnes rechercher dans la table users en implémentant le filtre suivant:

function inc_columns( $search_columns, $search, $this ) {
    $search_columns[] = 'user_email';
    $search_columns[] = 'user_nicename';
    $search_columns[] = 'display_name';

    return $search_columns;
}
add_filter('user_search_columns', 'inc_columns', 10, 3);

N'importe quelle lumière qui peut être éclairée sur la raison pour laquelle c'est serait formidable.

1
estin92

La combinaison d'une méta requête avec la recherche d'un mot clé renvoie des messages qui correspondent à la fois à la requête de recherche et au résultat de la méta requête (même si vous utilisez relation => OR dans la méta requête).

Cette réponse couvre un moyen d’atteindre le résultat escompté pour les publications. Vous devez modifier la requête avant d’obtenir le résultat. Cela devra cependant être modifié pour être utilisé avec une requête utilisateur WP. J'ai essayé de trouver une solution qui recherche le terme de recherche dans le user_nicename, le user_email et vos champs méta - non testés. Il pourrait donc être nécessaire de les peaufiner.

add_action( 'pre_user_query', 'user_meta_OR_search');
function user_meta_OR_search($q){
    if ($search = $q->get('_meta_or_search')){
        add_filter( 'get_meta_sql', function( $sql ) use ( $search ){
            global $wpdb;

            // Only run once:
            static $nr = 0; 
            if( 0 != $nr++ ) return $sql;

            // Modify WHERE part:
            $where = sprintf(
                " AND ( %s OR %s OR %s ) ",
                $wpdb->prepare( "{$wpdb->users}.user_nicename like '%%%s%%'", $search),
                $wpdb->prepare( "{$wpdb->users}.user_email like '%%%s%%'", $search),
                mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
            );

            $sql['where'] = $where;

            return $sql;
        });
    }
}

// Then, where you do the searching:
$search_term = "test";

$args = array(
    'fields' => ['ID'],
    'count_total' => true,
    'order' => 'ASC',   
    'orderby' => 'display_name',
    '_meta_or_search' => '*'.esc_attr( $search_term ).'*',
    "meta_query" => array(
        'relation' => 'OR',
        array(
            'key'     => 'first_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
        ),
        array(
            'key'     => 'last_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
              ),
        array(
            'key' => 'description',
            'value' => $search_term ,
            'compare' => 'LIKE'
        )
    )
);

$the_query = new WP_User_Query($args);

Une autre solution consiste à utiliser deux requêtes - une qui fait une recherche générale en utilisant s et l'autre en utilisant meta_query:

$args1 = array (
    'fields' => ['ID'],
    'count_total' => true,
    'order' => 'ASC',   
    'orderby' => 'display_name',
    'search' => '*'.esc_attr( $search_term ).'*'
);

$wp_user_query1 = new WP_User_Query($args1);
$args2 = array (
    'fields' => ['ID'],
    'count_total' => true,
    'order' => 'ASC',   
    'orderby' => 'display_name',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'first_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
        ),
        array(
            'key'     => 'last_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'description',
            'value' => $search_term ,
            'compare' => 'LIKE'
        )
    )
);
$wp_user_query2 = new WP_User_Query($args2);

$result = new WP_User_Query();
$result->results = array_unique( array_merge( $wp_user_query1->results, $wp_user_query2->results ), SORT_REGULAR );
$result->post_count = count( $result->results );

Cela fusionnera les résultats des deux requêtes en une troisième requête contenant les résultats de la recherche finale. Je n'ai pas testé cela, donc il faudra peut-être peaufiner!

3
Emil