wake-up-neo.net

WP Benutzerabfrage schlägt fehl, wenn Metaabfragen und Suchspalten durchsucht werden

Ich erstelle eine erweiterte Benutzersuche mit WP_User_Query, es tritt jedoch ein ungewöhnliches Verhalten auf. Ich versuche, mit einem Begriff zu suchen, von dem ich weiß, dass er in den Feldern user_nicename und user_email vorhanden ist, er wird jedoch nicht zurückgegeben, wenn ich meta_query in $ args einfüge.

Mit der folgenden einfachen Abfrage gibt WordPress beim Durchsuchen der Benutzertabellendaten alles erwartungsgemäß zurück, da der Begriff in user_nicename und user_email vorhanden ist.

$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);

Wenn ich dann jedoch eine meta_query in die Suche einführe, um das Benutzer-Meta abzugleichen, gibt die Abfrage überhaupt keine Ergebnisse zurück - obwohl sie zuvor mit der einfachen Anweisung Daten abgeglichen hat. Die meta_query lässt die $ args so aussehen:

$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);

Ich bestimme, welche Spalten aus der Benutzertabelle durchsucht werden sollen, indem ich den folgenden Filter implementiere:

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);

Es wäre großartig, wenn man ein Licht darauf werfen könnte, warum dies so ist.

1
estin92

Wenn Sie eine Meta-Abfrage mit einer Suche nach einem Schlüsselwort kombinieren, werden Beiträge zurückgegeben, die sowohl der Suchabfrage als auch dem Ergebnis der Meta-Abfrage entsprechen (auch wenn Sie in der Meta-Abfrage relation => OR verwenden).

Diese Antwort beschreibt einen Weg, um das erwartete Ergebnis für Posts zu erzielen. - Sie müssen die Abfrage ändern, bevor sie das Ergebnis abruft. Dies muss jedoch geändert werden, damit es mit einer WP Benutzerabfrage verwendet werden kann. Ich habe versucht, eine Lösung zu finden, die nach dem Suchbegriff in den Feldern user_nicename, user_email und Ihren Meta-Feldern sucht - ungetestet. Möglicherweise müssen Anpassungen vorgenommen werden.

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);

Eine andere Lösung besteht darin, zwei Abfragen zu verwenden - eine allgemeine Suche mit s und eine Suche mit 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 );

Dadurch werden die Ergebnisse der beiden Abfragen zu einer dritten Abfrage mit den endgültigen Suchergebnissen zusammengeführt. Ich habe das noch nicht getestet, daher muss es möglicherweise angepasst werden!

3
Emil