WP_Query “post_title LIKE '% bir şey'” ile?


44

Üzerinde bir WP_Queryile yapmam gerekiyor .LIKEpost_title

Bu düzenli ile başladım 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
    )
); 

Fakat gerçekte yapmak istediğim şey SQL'de şöyle görünüyor:

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

Çıktı beklediğim sonuçları yazdırıyor, ancak <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>sonuçları görüntülemek için normali kullanıyorum .
Ve bu işe yaramıyor $wpdb->get_results().

Burada anlattıklarımı nasıl elde edebilirim?

Yanıtlar:


45

Bunu bir filtre ile çözerdim WP_Query. Fazladan bir sorgu değişkeni algılayan ve bunu başlığın öneki olarak kullanan biri

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

Bu şekilde hala arayabilir WP_Query, sadece wpse18703_titleargüman olarak ünvanı iletirsiniz (veya ismi daha kısa bir şeye çevirirsiniz).


Bu bir şekilde eksik $wpdb->prepare().
kaiser

@kaiser: Uzun zaman oldu, ama bunun mümkün olmadığını düşünüyorum prepare(). $wpdb->prepare('LIKE "%s%%"', 'banana')geri dönecekti "LIKE ''banana'%'", bu yüzden sorguyu kendimiz inşa etmek ve kaçmayı da yapmak zorundayız.
Jan Fabry

1
@JanFabry Seni görmekten mutlu oldum agaaaaaaaain! :) Sohbete biraz zaman ayırın, hm? StopPress sizi gördüğüme sevindim. Bunun hakkında prepare(). Evet, bu çok zor ve bunu yapmadan önce birkaç kez denemek zorunda kaldım. Birşeyden Sadece yaptı: $wpdb->prepare( ' AND {$wpdb->posts}.post_title LIKE %s ', esc_sql( '%'.like_escape( trim( $term ) ).'%' ) ). esc_sql()Gereksiz ve sadece paranoyak olduğundan eminim .
kaiser

İçinde '(kesme işareti) olan bir dize arayamıyorsunuz gibi görünüyor . Sanırım kaçmak yüzünden mi? Henüz bir çözüm bulamadım
Vincent Decaux

19

Basitleştirilmiş:

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
Lütfen kodunuzla birlikte bir açıklama ekleyin.
s_ha_dum

2
Büyük sadeleştirme
Timo Huovinen

1
Kod bence kendi kendine açıkladı, benim için en azından. Komut dosyasını paylaştığınız için teşekkür ederiz.
Hassan Baba Han,

'$ Wpdb-> esc_like (' yerine 'esc_sql (like_escape ('
fdrv

@fdrv Haklısınız ama wp docs'a göre $ wpdb-> esc_like hala esc_sql () işlevine ihtiyaç duyuyor. Bu yüzden doğru kod esc_sql ($ wpdb-> esc_like ($ search_term)) olacağını düşünüyorum
Waqas Bukhary

16

Bu kodu güncellemek istediğinizde, esc_sql () 4.0 4.0 ve üstü sürümlerde kullanımdan kaldırıldığı için Wordpress 4.0 ve üzeri sürümlerde çalıştığınız.

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

Geri kalan şeyler aynı.

Ayrıca WP_Query argümanlarında s değişkenini kullanabildiğinizi , arama terimlerini iletmek için kullanacağımı, inanıyorum ki aynı zamanda post başlığını da arayacağımı belirtmek isterim .

Bunun gibi, böyle:

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

Tam olarak search_prod_titlenedir? Bunu başka bir şeyle değiştirmeli miyim?
Antonios Tsimourtos

Ne zamandan beri esc_sqlsınır dışı ediliyor? Değil. $wpdb->escapeöyle ... developer.wordpress.org/reference/functions/esc_sql
Jeremy

S parametresinin yazı içeriğini de aradığına ve istenen amaç olmayabilir. =)
Christine Cooper

10

Burada yayınlanan bazı hassas çözümler ile biraz basitleştirilmiş ve sterilize edilmiş bir sürümle geldim.

İlk olarak, posts_wherefiltre için yalnızca belirli koşullara uyan gönderileri göstermenizi sağlayan bir işlev yaratırız :

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

Şimdi cc_search_post_titlesorgu değişkenlerimize ekledik:

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

Sonunda filtreyi sorgunun etrafına sarın:

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 () kullanımı

Gönderileri alan belirli işlevler filtreleri çalıştırmaz, bu nedenle eklediğiniz posts_where filtre işlevleri sorguyu değiştirmez. Yayınlarınızı get_posts()sorgulamak için kullanmayı planlıyorsanız suppress_filters, argüman dizinizde false olarak ayarlamanız gerekir :

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

Şimdi kullanabilirsiniz 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 );

sParametre ne olacak ?

sParametresi mevcuttur:

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

Arama teriminizi sparametre çalışmasına eklerken yazı başlığını arayacak, yazı içeriğini de arayacaktır.

titleWP 4.4 ile eklenen parametre nedir ?

Bir arama terimini titleparametreye geçirme:

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

Küçük harfe duyarlıdır ve LIKEdeğildir %LIKE%. Bu ortalama arama hellobaşlığı Hello Worldveya ile yazılana geri dönmeyecek Hello.


Mükemmel. Parametre olarak 'post_title' i arıyordum ve açıkçası hiçbir şey bulamadım.
MastaBaba

7

Benden önce başka cevaplar üzerine inşa etmek, meta alanında bir kelime içeren bir yazıyı aramak istediğiniz durumda esneklik sağlamak için ya da yazı başlığında, bu seçeneği "title_filter_relation" argümanı ile veririm. Bu uygulamada, yalnızca "VEYA" veya "VE" girişlerinin varsayılan olarak "VE" şeklinde girmesine izin veriyorum.

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

İşte çok basit bir yazı tipi için "faq" tipi için kodun bir örneği: burada soru yazı başlığının kendisidir:

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
İyi bir içgörü, özel "sorgu değişkeni" ekleyerek filtreye WP_Queryerişebilmek için iletilen sorgu dizgisine erişilir posts_where.
Tom Auger,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.