「post_title LIKE 'something%'」を含むWP_Query?


44

私は何をする必要があるWP_QueryLIKEpost_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()

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

回答:


45

上のフィルターでこれを解決し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引数として渡すだけです(または、名前をもっと短い名前に変更します)。


これは何らかの形で欠けてい$wpdb->prepare()ます。
カイザー

@kaiser:久しぶりですが、これでは不可能だったと思いますprepare()$wpdb->prepare('LIKE "%s%%"', 'banana')が返される"LIKE ''banana'%'"ため、クエリを自分で作成し、エスケープする必要があります。
ヤンファブリ

1
@JanFabryお会いできてうれしいです!:)いつかチャットに立ち寄ってください。StopPressはあなたに会えてうれしいです。それについてprepare()。ええ、それはトリッキーです、私はそれを回避する前に、それを数回試さなければなりませんでした。私が作ったものから:$wpdb->prepare( ' AND {$wpdb->posts}.post_title LIKE %s ', esc_sql( '%'.like_escape( trim( $term ) ).'%' ) )。そして、私はそれesc_sql()が不必要で、ただ妄想的だと確信しています。
カイザー

'内部に(アポストロフィ)を含む文字列を検索できないようです。逃げたからだと思う?私はまだ解決策を見つけられませんでした
ヴィンセントデコー

19

簡略化:

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;

13
コードと一緒に説明を含めてください。
s_ha_dum

2
大幅な簡素化
ティモフオビネン14年

1
コードは、私にとって少なくとも自己説明だと思います。完全なスクリプトを共有していただきありがとうございます。
ハッサンダッドカーン

'esc_sql(like_escape('
fdrv

@fdrvあなたは正しいですが、wp docsによれば$ wpdb-> esc_likeはまだesc_sql()を必要とします。したがって、正しいコードはesc_sql($ wpdb-> esc_like($ search_term))
Waqas Bukhary

16

esc_sql()は4.0以降では非推奨であるため、wordpress 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);

正確にsearch_prod_titleは何ですか?これを別のものに変更する必要がありますか?
アントニオスチムルトス

いつからesc_sql廃止されますか?そうではありません。$wpdb->escapeしかし... developer.wordpress.org/reference/functions/esc_sql
ジェレミー

sパラメーターは投稿コンテンツも検索することに注意してください。これは望ましい目的ではない可能性があります。=)
クリスティーンクーパー

10

ここにいくつかの脆弱なソリューションが投稿されており、少し単純化され、サニタイズされたバージョンが付属しています。

最初に、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パラメーターworkに追加すると、投稿タイトルが検索されますが、投稿コンテンツ検索されます。

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

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

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

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


優れた。パラメーターとして「post_title」を探していましたが、明らかに何も見つかりませんでした。
マスタババ

7

私の前に他の答えに基づいて、メタフィールドまたは投稿のタイトルに単語を含む投稿を検索する状況に柔軟性を提供するために、引数「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);

1
優れた洞察、フィルターWP_Query内でアクセスできるように、渡されたクエリ引数にカスタム「クエリ変数」を追加しposts_whereます。
トム・オージェ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.