"post_title LIKE 'something %'"이있는 WP_Query?


44

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().

여기서 설명한 것을 어떻게 달성 할 수 있습니까?

답변:


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')return을 반환 "LIKE ''banana'%'"하므로 쿼리를 직접 작성하고 이스케이프 처리해야합니다.
Jan Fabry

1
@JanFabry 만나서 반가워요! :) 채팅에 시간이 좀 걸려요, 흠? StopPress가 당신을 만나서 반갑습니다. 그것에 대해 prepare(). 그래, 그것은 까다 롭고 나는 그것을 해결하기 전에 여러 번 시도해야했다. 내가 방금 만든 것에서 : $wpdb->prepare( ' AND {$wpdb->posts}.post_title LIKE %s ', esc_sql( '%'.like_escape( trim( $term ) ).'%' ) ). 그리고 나는 esc_sql()불필요하고 편집증 적이 라고 확신합니다 .
카이저

'내부에 (아포스트로피)가 있는 문자열을 검색 할 수없는 것 같습니다 . 탈출로 인한 것 같아요? 해결책을 찾지 못했습니다
Vincent Decaux

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
아주 단순화
티모 Huovinen

1
코드는 자기 설명이 필요하다고 생각합니다. 완전한 스크립트를 공유해 주셔서 감사합니다.
Hassan Dad Khan

'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? 이것을 다른 것으로 바꿔야합니까?
Antonios Tsimourtos

언제부터 esc_sql폐기 될 예정입니까? 그렇지 않습니다. $wpdb->escape하지만 ... developer.wordpress.org/reference/functions/esc_sql
Jeremy

s 매개 변수는 게시물 내용도 검색하므로 원하는 목표가 아닐 수 있습니다. =)
Christine Cooper

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매개 변수 작업에 추가 하면 게시물 제목이 검색되고 게시물 내용 검색됩니다.

[정보] 어떤 title매개 변수 WP 4.4에 추가 된?

검색어를 title매개 변수에 전달 :

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

대소 문자를 구분 LIKE하지 않습니다 %LIKE%. 대한이 평균 검색 hello제목으로 게시물을 반환하지 않습니다 Hello WorldHello.


우수한. 'post_title'을 매개 변수로 찾고 있었고 분명히 아무것도 찾지 못했습니다.
MastaBaba

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좋습니다.
Tom Auger 2012
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.