如何改善此管理员查询代码段,以避免在非元搜索中生成重复的结果?


11

我一直在玩一些代码片段,这些片段将元数据添加到管理员搜索中。

我找到的最好的片段是斯特凡诺(Stefano)关于这个问题的

但是,当搜索非元术语时,它似乎有1个烦人的错误。

这是我本地开发安装的一些内容。我已经在屏幕上打印了两个MySQL查询。

我正在测试的单个CPT帖子的视图

我正在测试的单个CPT帖子的视图

这是按预期工作的代码,允许我从管理员搜索元数据

这是按预期工作的代码,允许我从管理员搜索元数据

不幸的是,该代码在非元匹配中创建了重复项,在本例中为帖子标题

不幸的是,该代码在非元匹配中创建了重复项,在本例中为帖子标题

显示骗子的职位状态,职位类型和职位祖先的抓取

显示骗子的职位状态,职位类型和职位祖先的抓取

这是我正在运行的代码,与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' );  

也许它也列出了修订?
passatgt

我以为我只看出版的,因为我删除了未决的,私有的,草稿的和未来的。没注意到版本类型。
jnthnclrk

嗯,似乎不是“修订”状态:codex.wordpress.org/Post_Status
jnthnclrk

尝试在其中一列中打印post_type或post_id,我认为修订版是post类型,因此,如果您可以看到修订版,则结果中也包含该类型。但是我还可以看到您只显示列表帖子类型的结果,所以我认为我错了。但是值得一试:)
passatgt

添加了具有职位状态,职位类型和职位祖先的新职位。
jnthnclrk

Answers:


11

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

4

谢谢大家的辛勤工作。这段代码为我提供了大部分帮助,但是使用WP 3.8时,我遇到了SQL非唯一表/别名错误,因此我进行了一些更改。为了使其在我的设置中起作用,我必须设置一个$ 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_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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.