問題描述

我一直在玩程式碼片段,將後設資料新增到管理員搜尋。

我發現的最好的程式碼片段是由 Stefano on this question 編寫的。

但是,在搜尋 non-meta 條款時,似乎有 1 個煩人的錯誤。

這裡是我本地開發人員安裝的一些抓取。我列印了 2 個 MySQL 查詢到螢幕上。

檢視我用於測試的單個 CPT 帖子

這是程式碼正常工作,允許我從管理員搜尋後設資料

不幸的是,程式碼在 non-meta 比賽中建立了重複項,在這種情況下就是標題

抓住顯示帖子狀態,帖子型別和帖子祖先的笨蛋

A grab showing the post status, post type and post ancestors of dupes

這是我正在執行的程式碼,它基本上與 Stefano 的相同,但是我粗暴的嘗試使查詢工作。

/*
 * 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_titles+LIKEs*('[^']+')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' );  

最佳解決方案

GROUP BY 語句可以在 JOIN 之後對您的帖子進行分組。對於 Wordpress,您可以使用 posts_groupby 過濾器。

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

次佳解決方案

謝謝你的工作,這個人,這個程式碼讓我大部分的方式在那裡,但使用 WP 3.8 我得到一個 SQL non-unique 表/別名錯誤,所以我做了一些改變。為了在我的設定上工作,我必須設定一個 $ wpdb-> postmeta 別名,用於 JOIN 語句。我也只檢查一次,看看是否應該使用鉤子,所以每次都不要點火。希望這有助於某人!

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_titles+LIKEs*('[^']+')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

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。