Bagaimana cara meningkatkan cuplikan permintaan admin ini untuk menghindari menghasilkan hasil duplikat pada pencarian non-meta?

11

Saya telah bermain-main dengan cuplikan kode yang menambahkan data meta ke pencarian admin.

Cuplikan terbaik yang saya temukan ditulis oleh Stefano pada pertanyaan ini .

Namun, tampaknya ada 1, bug yang mengganggu ketika mencari istilah non-meta.

Berikut ini beberapa hasil dari instalasi dev lokal saya. Saya telah mencetak 2 query MySQL ke layar.

Lihat posting CPT tunggal yang saya gunakan untuk menguji

Lihat posting CPT tunggal yang saya gunakan untuk menguji

Ini adalah kode yang berfungsi seperti yang diharapkan dan memungkinkan saya untuk mencari data meta dari admin

Ini adalah kode yang berfungsi seperti yang diharapkan dan memungkinkan saya untuk mencari data meta dari admin

Sayangnya, kode ini membuat duplikat pada kecocokan non-meta, dalam hal ini pada judul posting

Sayangnya, kode ini membuat duplikat pada kecocokan non-meta, dalam hal ini pada judul posting

Perebutan yang menunjukkan status kiriman, jenis kiriman, dan kiriman leluhur dupes

! Perebutan yang menunjukkan status kiriman, jenis kiriman, dan kiriman leluhur dupes

Berikut adalah kode yang saya jalankan, pada dasarnya sama dengan kode Stefano, tetapi dengan upaya kasar saya untuk membuat kueri berfungsi.

/*
 * Search custom fields from admin keyword searches
 */

function rel_search_join( $join ) {
    global $pagenow, $wpdb;
    if ( is_admin() && $pagenow == 'edit.php' && $_GET['post_type'] == 'listings' && $_GET['s'] != '') {    
        $join .= 'LEFT JOIN ' . $wpdb->postmeta . ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }
    echo '<br><strong>JOIN</strong>: ';
    print_r ( $join );
    echo '<br>';
    return $join;
}
add_filter('posts_join', 'rel_search_join' );

function rel_search_where( $where ) {
    global $pagenow, $wpdb;
    if ( is_admin() && $pagenow == 'edit.php' && $_GET['post_type']=='listings' && $_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 );
        $where = str_replace( "OR wp_posts.post_status = 'pending'", "", $where );
        $where = str_replace( "OR wp_posts.post_status = 'private'", "", $where );
        $where = str_replace( "OR wp_posts.post_status = 'draft'", "", $where );
        $where = str_replace( "OR wp_posts.post_status = 'future'", "", $where );
    }
    echo '<br><strong>WHERE</strong>: ';
    print_r ( $where );
    echo '<br>';
    return $where;
}
add_filter( 'posts_where', 'rel_search_where' );  
jnthnclrk
sumber
Mungkin daftar revisi juga?
passatgt
Saya pikir saya hanya melihat diterbitkan, karena saya dihapus tertunda, pribadi, konsep & masa depan. Tidak melihat jenis revisi.
jnthnclrk
Hmmm, sepertinya bukan status "revisi": codex.wordpress.org/Post_Status
jnthnclrk
mencoba untuk mencetak_r jenis posting atau id posting di salah satu kolom, saya pikir revisi adalah jenis posting, jadi jika Anda dapat melihat revisi, Anda memiliki itu juga dalam hasil. Tetapi saya juga dapat melihat bahwa Anda hanya menampilkan hasil dari jenis posting listing, jadi saya pikir saya salah. Tetapi patut dicoba :)
passatgt
Menambahkan tangkapan baru dengan status pos, jenis pos, dan leluhur pos.
jnthnclrk

Jawaban:

11

Sebuah GROUP BYpernyataan dapat mengelompokkan pos Anda setelah JOIN. Untuk Wordpress Anda dapat menggunakan posts_groupbyfilter.

add_filter( 'posts_groupby', 'my_post_limits' );
function my_post_limits($groupby) {
    global $pagenow, $wpdb;
    if ( is_admin() && $pagenow == 'edit.php' && $_GET['post_type']=='listings' && $_GET['s'] != '' ) {
        $groupby = "$wpdb->posts.ID";
    }
    return $groupby;
}
epilektrik
sumber
4

Terima kasih atas pekerjaan Anda dalam hal ini, teman-teman. Kode ini membuat saya sebagian besar jalan di sana, tetapi menggunakan WP 3.8 saya mendapatkan kesalahan tabel / alias SQL non-unik, jadi saya membuat beberapa perubahan. Agar bisa berfungsi pada setup saya, saya harus menetapkan $ postpeta $ wpdb-> yang digunakan dalam pernyataan GABUNG. Saya juga memeriksa hanya memeriksa sekali untuk melihat apakah kait harus digunakan sehingga mereka tidak menyala setiap waktu. Semoga ini bisa membantu seseorang!

global $postmeta_alias, $is_specials_search;
$cpt_name = 'special';
$postmeta_alias = 'pdpm'; // Change this to whatever your custom post type is
$is_specials_search = is_admin() && $pagenow=='edit.php' && isset( $_GET['post_type'] ) && $_GET['post_type']==$cpt_name && isset( $_GET['s'] );

// Extend search to include 'description' field
if ( $is_specials_search ) {
  add_filter( 'posts_join',      'pd_description_search_join' );
  add_filter( 'posts_where',     'pd_description_search_where' );
  add_filter( 'posts_groupby',   'pd_search_dupe_fix' );
}

function pd_description_search_join ($join){
  global $pagenow, $wpdb, $postmeta_alias, $is_specials_search;

  if ( $is_specials_search )  
    $join .='LEFT JOIN '.$wpdb->postmeta. ' as ' . $postmeta_alias . ' ON '. $wpdb->posts . '.ID = ' . $postmeta_alias . '.post_id ';

  return $join;
} // END search_join

function pd_description_search_where( $where ){
  global $pagenow, $wpdb, $postmeta_alias, $is_specials_search;

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

  return $where;
} // END search_where

function pd_search_dupe_fix($groupby) {
    global $pagenow, $wpdb, $is_specials_search;

    if ( $is_specials_search )
      $groupby = "$wpdb->posts.ID";

    return $groupby;
} // END pd_search_dupe_fix
souverian
sumber