Yönetici bağlamında arama ekranında arama içeriğini genişletme


34

Özel bir gönderi türü oluşturdum ve ona bazı özel alanlar ekledim. Şimdi, yazarların özel posta listesi ekranında (yönetici arka ucunda) meta alanlarında da gerçekleştirilebilmelerini ve yalnızca başlığa ve içeriğe her zamanki gibi bakmamalarını sağlayacakları bir arama yapmak istiyorum.

Nereye bağlayabilirim ve hangi kodu kullanmalıyım?

Örnek resim görüntü tanımını buraya girin

Stefano


1
Eski bir soru, ama ... e-posta adreslerini ve isimlerini ekran görüntülerinden gizlemek istiyorum ...
Erenor Paz

Yanıtlar:


37

Postmeta tablosunda join öğesini ekleyerek ve where yan tümcesini değiştirerek sorguyu filtrelemeyi çözdüm. WHERE yan tümcesini filtrelemeyle ilgili ipuçları (genellikle düzenli ifade arama ve değiştirme gerektirir) burada kodeksi yer almaktadır :

add_filter( 'posts_join', 'segnalazioni_search_join' );
function segnalazioni_search_join ( $join ) {
    global $pagenow, $wpdb;

    // I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
    if ( is_admin() && 'edit.php' === $pagenow && 'segnalazioni' === $_GET['post_type'] && ! empty( $_GET['s'] ) ) {    
        $join .= 'LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }
    return $join;
}

add_filter( 'posts_where', 'segnalazioni_search_where' );
function segnalazioni_search_where( $where ) {
    global $pagenow, $wpdb;

    // I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
    if ( is_admin() && 'edit.php' === $pagenow && 'segnalazioni' === $_GET['post_type'] && ! empty( $_GET['s'] ) ) {
        $where = preg_replace(
            "/\(\s*" . $wpdb->posts . ".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(" . $wpdb->posts . ".post_title LIKE $1) OR (" . $wpdb->postmeta . ".meta_value LIKE $1)", $where );
    }
    return $where;
}

1
Vaov! Sadece aradığım şeyi. Bununla birlikte, bir hata bulabileceğimi düşünüyorum, posta başlığı üzerinde arama yaparken, sonuçlarda 5 kez çoğaltılan bir eşleşme elde ediyorum!?! imgur.com/eE52gIA
jnthnclrk

İşte basılan SQL ile başka bir kapmak: tinypic.com/view.php?pic=124tqb6&s=5 Neden 5 öğeyi aldığımı çözemiyorum !?!
jnthnclrk

1
Dupe hatasını düzeltmek üzerine ayrı bir soru yayınladı: wordpress.stackexchange.com/questions/111185/…
jnthnclrk

Bu ve aşağıdaki yazı benim için yararlı oldu. Şimdi yazarın aranmasını dahil etmenin bir yolunu bulmak ve onlar tarafından yapılan yayınları göstermek için.
Shawn Rebelo

@Stefano, arama sonucu çalışıyor. Bir sorun var, varsayılan alan "Mesaj başlığı", arama kaydı birçok zaman ve yönetici tarafından tekrarlanıyor. Bakınız: imgur.com/a/W4wmXhO
Süper Model

10

Stefano'nun cevabı harika ancak farklı bir maddeden yoksun:

function segnalazioni_search_distinct( $where ){
    global $pagenow, $wpdb;

    if ( is_admin() && $pagenow=='edit.php' && $_GET['post_type']=='segnalazioni' && $_GET['s'] != '') {
    return "DISTINCT";

    }
    return $where;
}
add_filter( 'posts_distinct', 'segnalazioni_search_distinct' );

Yukarıdaki kodu ekleyin ve güncelleyin; yinelenmeden çalışacaktır.


7

Bu çalışacak,

function custom_search_query( $query ) {
    $custom_fields = array(
        // put all the meta fields you want to search for here
        "rg_first_name",
        "rg_1job_designation"
    );
    $searchterm = $query->query_vars['s'];

    // we have to remove the "s" parameter from the query, because it will prevent the posts from being found
    $query->query_vars['s'] = "";

    if ($searchterm != "") {
        $meta_query = array('relation' => 'OR');
        foreach($custom_fields as $cf) {
            array_push($meta_query, array(
                'key' => $cf,
                'value' => $searchterm,
                'compare' => 'LIKE'
            ));
        }
        $query->set("meta_query", $meta_query);
    };
}
add_filter( "pre_get_posts", "custom_search_query");

1
Pleas kodunuzu uygun şekilde girin ve bunun neden ve nasıl işe yarayacağına dair bir açıklama yapın .
tfrommen

Her ne kadar ilk önce oylamasam da, bunun maalesef her aramada çalışacağının farkına vardım ki, aynı arama önden aramayı bozabilir.
Maciej Paprocki

Başa bir çek eklemek if ( $query->query['post_type'] != 'your_custom_post_type' ){ return; }, fonksiyonun üst kısmının diğer aramalarda çalışmasını engeller. Bu cevaptaki tekniğin artık post_title dosyasını aramadığını ve onu tekrar eklemenin önemsiz olmadığını unutmayın.
jwinn

Bir başka sorun - gösterge “<anahtar>” için arama sonuçları aramalar get_search_query()geçilmesi salık get_query_var( 's' ). "S" boş dize olarak ayarlandığından, “” için arama sonuçları tırnak işaretleri arasında her zaman boş bir değere sahip olacaktır. Bu sorunun üstesinden gelen bir çözüm var mı?
jschrab

1

Cevap 1: Bu kodu fonksiyon dosyasına ekleyin ve özel yazı tipinizde kullandığınız daha fazla sütun adını değiştirin ve ekleyin.

function extend_admin_search( $query ) {

    // use your post type
    $post_type = 'document';
    // Use your Custom fields/column name to search for
    $custom_fields = array(
        "_file_name",
    );

    if( ! is_admin() )
        return;

    if ( $query->query['post_type'] != $post_type )
        return;

    $search_term = $query->query_vars['s'];

    // Set to empty, otherwise it won't find anything
    $query->query_vars['s'] = '';

    if ( $search_term != '' ) {
        $meta_query = array( 'relation' => 'OR' );

        foreach( $custom_fields as $custom_field ) {
            array_push( $meta_query, array(
                'key' => $custom_field,
                'value' => $search_term,
                'compare' => 'LIKE'
            ));
        }

        $query->set( 'meta_query', $meta_query );
    };
}

add_action( 'pre_get_posts', 'extend_admin_search' );

Cevap 2: Önerilen Bu kodu fonksiyon dosyasında herhangi bir değişiklik yapmadan kullanın.

function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

0

Bu bir arama değil, ancak bazıları belirgin bir değere göre “seçim” yapıyor.

Dosya fonksiyonları- iworks-posts-filter.zip Düzenli gönderim için bazı meta_key ile filtre ekleme konusunda bir örneğiniz var. Dönüştürmenin kolay olduğunu düşünüyorum.


Yardımın için teşekkürler ... Şu anda ekine bakacağım. Araştırmamın sonuçlarını size bildireceğim ;-) Stefano
Stefano

Marcin Sanırım "tarihe kadar" vb. Gibi filtrelere başvurduğunuzu düşünüyorum ... ama yukarıdaki "ücretsiz arama" alanına girmem gerekiyor. Her neyse ben sadece çözüm yolumu yayınladım, belki yardımcı olur Yine de teşekkürler!
Stefano

0

Burada kodun sürümü, pre_get_posts içindeki aramanın WP_Query parametresinin meta_query parametresini değiştiren birkaç cevapta artık post_title'da arama yapmıyordu. Her iki gönderiyi de araştırabilme kabiliyeti ekleyerek, OR meta değerleri WP_Query'de doğrudan SQL değiştirilmeden yapılamaz, çünkü bu soru üzerinde durulur: Bir arama sorgusu ('s') ile meta sorguyu kullanma ('meta_query')

Buradaki bazı teknikler, preg_replaces ve çok fazla SQL modifikasyonundan kaçınan çalışan bir sürüm elde etmek için bir araya getirdim (Tamamen önlenebilir olmasını diliyorum). Tek dezavantajı, bir aramadan sonra sayfanın üstündeki altyazı metninde "Arama Sonuçları" ". Eklentimin özel gönderi türü için bunu CSS ile gizledim.

/**
 * Extend custom post type search to also search meta fields
 * @param  WP_Query $query
 */
function extend_cpt_admin_search( $query ) {
  // Make sure we're in the admin area and that this is our custom post type
  if ( !is_admin() || $query->query['post_type'] != 'your_custom_post_type' ){
    return;
  }

  // Put all the meta fields you want to search for here
  $custom_fields = array(
    "your_custom_meta_field",
    "your_custom_meta_field2",
    "your_custom_meta_field3"
  );
  // The string submitted via the search form
  $searchterm = $query->query_vars['s'];

  // Set to empty, otherwise no results will be returned.
  // The one downside is that the displayed search text is empty at the top of the page.
  $query->query_vars['s'] = '';

  if ($searchterm != ""){
    // Add additional meta_query parameter to the WP_Query object.
    // Reference: https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
    $meta_query = array();
    foreach($custom_fields as $cf) {
      array_push($meta_query, array(
        'key' => $cf,
        'value' => $searchterm,
        'compare' => 'LIKE'
      ));
    }
    // Use an 'OR' comparison for each additional custom meta field.
    if (count($meta_query) > 1){
      $meta_query['relation'] = 'OR';
    }
    // Set the meta_query parameter
    $query->set('meta_query', $meta_query);


    // To allow the search to also return "OR" results on the post_title
    $query->set('_meta_or_title', $searchterm);
  }
}
add_action('pre_get_posts', 'extend_cpt_admin_search');



/**
 * WP_Query parameter _meta_or_title to allow searching post_title when also
 * checking searching custom meta values
 * https://wordpress.stackexchange.com/questions/78649/using-meta-query-meta-query-with-a-search-query-s
 * https://wordpress.stackexchange.com/a/178492
 * This looks a little scary, but basically it's modifying the WHERE clause in the 
 * SQL to say "[like the post_title] OR [the existing WHERE clause]"
 * @param  WP_Query $q
 */
function meta_or_title_search( $q ){
  if( $title = $q->get( '_meta_or_title' ) ){
    add_filter( 'get_meta_sql', function( $sql ) use ( $title ){
      global $wpdb;

      // Only run once:
      static $nr = 0;
      if( 0 != $nr++ ) return $sql;

      // Modified WHERE
      $sql['where'] = sprintf(
          " AND ( (%s) OR (%s) ) ",
          $wpdb->prepare( "{$wpdb->posts}.post_title LIKE '%%%s%%'", $title),
          mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
      );

      return $sql;
    });
  }
}
add_action('pre_get_posts', 'meta_or_title_search');
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.