web-dev-qa-db-ja.com

非メタ検索で重複する結果が生成されないようにするには、この管理者クエリスニペットをどのように改善すればよいですか。

私は管理検索にメタデータを追加するコードスニペットで遊んできました。

私が見つけた最高のスニペットはこの質問に関して Stefanoによって書かれました

ただし、メタ以外の用語を検索すると1、迷惑なバグがあるようです。

これが私のローカル開発者インストールからのいくつかのつかみです。私は2つのMySQLクエリを画面に表示しました。

テストに使用している単一のCPT投稿の表示

View of the single CPT post I'm using to test

これは期待どおりに機能し、管理者からメタデータを検索できるようにするコードです。

This is the code working as expected and allowing me to search meta data from admin

残念ながら、このコードではメタ以外の一致(この場合は役職)に重複があります

Unfortunately the code creates duplicates on non-meta matches, in this case on post title

デュープの投稿ステータス、投稿タイプ、投稿先祖を表示するグラブ

デュペの投稿ステータス、投稿タイプ、投稿の祖先を表示するグラブ

これが私が実行しているコードです、それは基本的に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_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' );  
11
jnthnclrk

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

皆さん、これに取り組んでくれてありがとう。このコードはほとんどの場合問題なく動作しますが、WP 3.8を使用すると、SQLで一意でないテーブル/エイリアスエラーが発生していたため、いくつか変更を加えました。私の設定でうまくいくためには、JOINステートメントで使われていた$ wpdb-> postmetaエイリアスを設定しなければなりませんでした。また、フックが毎回起動しないようにフックを使用する必要があるかどうかを確認するために1回だけチェックします。これが誰かに役立つことを願っています!

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
4
souverian