Como eu melhoro este snippet de consulta de administrador para evitar gerar resultados duplicados em pesquisas que não são meta?

11

Estou brincando com trechos de código que adicionam metadados a pesquisas administrativas.

O melhor snippet que encontrei foi escrito por Stefano sobre esta questão .

No entanto, parece ter um bug irritante ao pesquisar termos não-meta.

Aqui estão algumas tentativas do meu dev de instalação local. Eu imprimi as duas consultas do MySQL na tela.

Vista da única postagem do CPT que estou usando para testar

Esteéocódigoquefuncionacomoesperadoepermitequeeupesquisemetadadosdoadministrador

Infelizmente, o código cria duplicatas em correspondências não meta, neste caso, no título da postagem

Umacapturamostrandoostatusdapostagem,tipodepostagemepós-ancestraisdasduplas

! Um grab que mostra o status do post, post tipo e post ancestors of dupes

Aqui está o código que estou rodando, é basicamente o mesmo que o de Stefano, mas com minhas tentativas grosseiras de fazer a consulta funcionar.

/*
 * 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' );  
    
por jnthnclrk 22.08.2013 / 14:33

2 respostas

11

Uma declaração GROUP BY pode agrupar suas postagens após o JOIN . Para o Wordpress, você pode usar o filtro 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;
}
    
por epilektric 25.08.2013 / 12:20
4

Obrigado pelo seu trabalho nisto, pessoal. Este código me pegou a maior parte do caminho, mas usando o WP 3.8 eu estava recebendo um erro de tabela / alias não exclusivo do SQL, então fiz algumas alterações. Para que funcione na minha configuração, eu tive que configurar um alias postmeta $ wpdb- > que foi usado na instrução JOIN. Eu também verifico apenas uma vez para ver se os ganchos devem ser usados para que não disparem todas as vezes. Espero que isso ajude alguém!

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
    
por souverian 30.12.2013 / 19:47