web-dev-qa-db-ja.com

WP メタクリや検索列を検索するときにユーザエリが失敗する

WP_User_Queryを使用して高度なユーザー検索を作成していますが、いくつかの異常な動作が発生しています。 user_nicenameフィールドとuser_emailフィールドに存在することがわかっている用語で検索しようとしていますが、$ argsにmeta_queryを含めると失敗します。

下記の単純なクエリを使用して、usersテーブルのデータを検索するとき、単語がuser_nicenameとuser_emailに存在するため、WordPressは期待通りにすべてを返します。

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

しかし、ユーザーmetaをチェックするためにmeta_queryを検索に導入すると、クエリは以前の単純なステートメントを使用したデータのマッチングにもかかわらず、まったく結果を返しません。 meta_queryは$ argsを以下のようにします。

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

次のフィルタを実装して、usersテーブルから検索する列を決定します。

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

これがなぜであるかについて当てることができるどんな光でも素晴らしいでしょう。

1
estin92

メタクエリーとキーワードの検索を組み合わせると、検索クエリーとメタクエリーの結果の両方に一致する投稿が返されます(メタクエリーでrelation => ORを使用している場合でも)。

この答え は投稿に対してあなたの期待される結果を達成する方法をカバーしています。それは結果を取得する前にクエリを修正する必要があります。ただし、これをWP User Queryで使用するには修正する必要があります。 user_nicenameuser_emailおよびあなたのメタフィールドで検索語を検索する解決策を試みました - テストされていないので、微調整が必​​要かもしれません。

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

もう1つの解決策は、2つのクエリを使用することです。1つはsを使用して一般的な検索を行い、もう1つは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 );

これにより、2つのクエリの結果が最終的な検索結果を含む3番目のクエリにマージされます。私はこれをテストしていないので、少し調整が必要かもしれません!

3
Emil