web-dev-qa-db-ja.com

WP_Queryで%keywords%の用語を含むすべての製品を検索します

WP_Queryを使用して、入力フィールドに入力されたすべての製品用語を検索したいと思います。これが私のWP_Queryコードです。

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = array(
    'post_type'         => 'product',
    'product_cat'       => 'construction',
    'posts_per_page'    => 12,
    'paged'             => $paged,
    'tax_query' => array(
        array(
            'taxonomy'  => 'pa_reference-p-no',
            'field'     => 'slug',
            'terms'     => $input_search_txt
        )
    );
);

$loop = new WP_Query( $args );

'$ input_search_txt'は、入力フィールドに入力されたテキストです。 「pa_reference-p-no」にこのテキストを含むすべての製品を検索したい。 たとえば、「123」を検索した場合、「12345」または「123456」という用語が含まれる製品を検索します。

しかし、今私は「123」という用語の製品しか見ることができません。

誰かに助けてもらいたい。

1
Mike

残念ながら、tax_queryにはmeta_queryのようなcompare一致修飾子がないため、「LIKE」演算子を使用したワイルドカード検索が可能です。したがって、別のアプローチが必要です。この問題を解決する方法は2つ考えられます。

1)グローバル $ wpdb オブジェクトを使用してテキスト検索に一致するすべての用語を検索し、それらの用語IDを使用して operator 一致修飾子を現在のクエリに追加します。 [編集:デバッグ行を追加しました enable WP_DEBUG]

    global $wpdb; 
    $term_ids = $wpdb->get_results( 
        "
        SELECT {$wpdb->terms}.term_id 
        FROM {$wpdb->terms}, {$wpdb->term_taxonomy}
        WHERE {$wpdb->terms}.term_id =  {$wpdb->term_taxonomy}.term_id
            AND {$wpdb->term_taxonomy}.taxonomy LIKE 'pa_reference-p-no'
            AND {$wpdb->terms}.slug LIKE '%{$input_search_txt}%'
        ",
        ARRAY_N
    );
    //you can debug your term id results at this point by printing them in your log file, make sure WP_DEBUG is set to true in your wp_config.php file.
    error_log('TERM IDS:'.print_r($term_ids,true)); //should be an array of term ids.
    $args = array(
        'post_type'         => 'product',
        'product_cat'       => 'construction',
        'posts_per_page'    => 12,
        'paged'             => $paged,
        'tax_query' => array(
            array(
                'taxonomy'  => 'pa_reference-p-no',
                'terms'     => $term_ids,
                'operator'  => 'IN'
            )
        );
    );

    $loop = new WP_Query( $args );

2)2番目の方法は、 クエリフィルターposts_where フィルターを使用して、カスタムSQL条件をクエリに追加することです。したがって、クエリを簡略化して「製品」の投稿のみを検索し、次を使用して分類条件を変更します。

        add_filter( 'posts_where' , 'posts_where', 10,2 );

        function posts_where( $where , $query) {

            if( 'product' == $query->query_vars['post_type'] && !$query->is_main_query() && !$query->is_admin() ) {
                global $wpdb;

                if ( isset( $_POST['input_search_txt'] ) && !empty( $_POST['input_search_txt'] ) ) {

                   $where .= 
                   " 
                     AND {$wpdb->terms}.term_id =  {$wpdb->term_taxonomy}.term_id
                     AND {$wpdb->term_taxonomy}.taxonomy LIKE 'pa_reference-p-no'
                     AND {$wpdb->terms}.slug LIKE '%{$_POST['input_search_txt'];}%'
                 ";
                }
            }
            return $where;
        }

私はそれらをテストしていませんが、これらのソリューションはどちらも機能するはずです。 1つ目はデバッグが簡単で、現在のクエリのみをターゲットにします。 2番目のソリューションは、DBへのヒットが1つ少なくなるため、より効率的です。ただし、初期状態で$queryをフィルタリングしないと、他のカスタムクエリが影響を受け、デバッグが非常に難しい場合があります。

理解に問題がある場合は、下のコメントでお知らせください。

1
Aurovrata