web-dev-qa-db-ja.com

"post_title LIKE 'something%'"を含むWP_Query?

WP_Query上でLIKEを使ってpost_titleを実行する必要があります。

私はこの通常のWP_Queryから始めました:

$wp_query = new WP_Query( 
    array (
        'post_type'        => 'wp_exposants',
        'posts_per_page'   => '1',
        'post_status'      => 'publish',
        'orderby'          => 'title', 
        'order'            => 'ASC',
        'paged'            => $paged
    )
); 

しかし、私が実際にやりたいことは、SQLでは次のようになります。

$query = "
        SELECT      *
        FROM        $wpdb->posts
        WHERE       $wpdb->posts.post_title LIKE '$param2%'
        AND         $wpdb->posts.post_type = 'wp_exposants'
        ORDER BY    $wpdb->posts.post_title
";
$wpdb->get_results($query);

期待通りの結果が出力されますが、結果を表示するには通常の<?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>を使います。
そしてそれは$wpdb->get_results()ではうまくいきません。

ここで説明したことをどのようにして達成できますか?

43
Ludo

これをWP_Queryのフィルタで解決します。追加のクエリ変数を検出し、それをタイトルのプレフィックスとして使用するもの。

add_filter( 'posts_where', 'wpse18703_posts_where', 10, 2 );
function wpse18703_posts_where( $where, &$wp_query )
{
    global $wpdb;
    if ( $wpse18703_title = $wp_query->get( 'wpse18703_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'' . esc_sql( $wpdb->esc_like( $wpse18703_title ) ) . '%\'';
    }
    return $where;
}

このようにしてもWP_Queryを呼び出すことができ、タイトルをwpse18703_title引数として渡すだけです(または名前をもっと短い名前に変更する)。

44
Jan Fabry

簡体字

function title_filter( $where, &$wp_query )
{
    global $wpdb;
    if ( $search_term = $wp_query->get( 'search_prod_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $search_term ) ) . '%\'';
    }
    return $where;
}

$args = array(
    'post_type' => 'product',
    'posts_per_page' => $page_size,
    'paged' => $page,
    'search_prod_title' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'
);

add_filter( 'posts_where', 'title_filter', 10, 2 );
$wp_query = new WP_Query($args);
remove_filter( 'posts_where', 'title_filter', 10, 2 );
return $wp_query;
17
Rao

Esc_sql()は4.0以降では非推奨であるため、皆さんがこのワードプレス4.0以降で作業したコードを更新したいと考えていました。

function title_filter($where, &$wp_query){
    global $wpdb;

    if($search_term = $wp_query->get( 'search_prod_title' )){
        /*using the esc_like() in here instead of other esc_sql()*/
        $search_term = $wpdb->esc_like($search_term);
        $search_term = ' \'%' . $search_term . '%\'';
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE '.$search_term;
    }

    return $where;
}

他のものは同じです。

また、WP_Queryの引数内で s 変数を使用して検索語を渡すこともできます。これにより、投稿タイトルも検索されます。

このような:

$args = array(
    'post_type' => 'post',
    's' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'        
);
$wp_query = new WP_Query($args);
16
Ashan Jay

ここに掲載されているいくつかの脆弱な解決策で、私は少し簡素化され、衛生化されたバージョンが付属しています。

まず、特定の条件に一致する投稿のみを表示できるposts_whereフィルタ用の関数を作成します。

function cc_post_title_filter($where, &$wp_query) {
    global $wpdb;
    if ( $search_term = $wp_query->get( 'cc_search_post_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . $wpdb->esc_like( $search_term ) . '%\'';
    }
    return $where;
}

それでは、クエリ引数にcc_search_post_titleを追加します。

$args = array(
    'cc_search_post_title' => $search_term, // search post title only
    'post_status' => 'publish',
);

そして最後にクエリをフィルタで囲みます。

add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
$query = new WP_Query($args);
remove_filter( 'posts_where', 'cc_post_title_filter', 10 );

Get_posts()を使う

投稿を取得する特定の関数はフィルタを実行しないため、添付したposts_whereフィルタ関数はクエリを変更しません。投稿のクエリにget_posts()を使用する予定の場合は、引数配列でsuppress_filtersをfalseに設定する必要があります。

$args = array(
    'cc_search_post_title' => $search_term,
    'suppress_filters' => FALSE,
    'post_status' => 'publish',
);

これでget_posts()を使うことができます。

add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
$posts = get_posts($args);
remove_filter( 'posts_where', 'cc_post_title_filter', 10 );

sパラメータはどうですか?

sパラメータが利用可能です。

$args = array(
    's' => $search_term,
);

sパラメータに検索語を追加して投稿のタイトルを検索しますが、/投稿のコンテンツも検索します。

WP 4.4で追加されたtitleパラメータはどうですか?

検索語をtitleパラメータに渡す:

$args = array(
    'title' => $search_term,
);

%LIKE%ではなく、大文字と小文字が区別されLIKEです。つまり、helloを検索しても、タイトルがHello WorldまたはHelloの投稿は返されません。

9

投稿のタイトルにメタフィールドORに含まれるWordを含む投稿を検索する状況での柔軟性を提供するために、私の前にある他の回答に基づいて、私は引数を通してそのオプションを与えますtitle_filter_relation。」この実装では、デフォルトの "AND"で "OR"または "AND"入力のみを許可します。

function title_filter($where, &$wp_query){
    global $wpdb;
    if($search_term = $wp_query->get( 'title_filter' )){
        $search_term = $wpdb->esc_like($search_term); //instead of esc_sql()
        $search_term = ' \'%' . $search_term . '%\'';
        $title_filter_relation = (strtoupper($wp_query->get( 'title_filter_relation'))=='OR' ? 'OR' : 'AND');
        $where .= ' '.$title_filter_relation.' ' . $wpdb->posts . '.post_title LIKE '.$search_term;
    }
    return $where;
}

これは、質問が投稿のタイトルそのものである、非常に単純な投稿の種類 "faq"に対して実行中のコードの例です。

add_filter('posts_where','title_filter',10,2);
$s1 = new WP_Query( array(
    'post_type' => 'faq',
    'posts_per_page' => -1,
    'title_filter' => $q,
    'title_filter_relation' => 'OR',
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'faq_answer',
            'value' => $q,
            'compare' => 'LIKE'
        )
    )
));
remove_filter('posts_where','title_filter',10,2);
7
David Choy