¿Cómo puedo mejorar este fragmento de consulta de administración para evitar generar resultados duplicados en búsquedas no meta?

11

He estado jugando con fragmentos de código que agregan metadatos a las búsquedas de administradores.

El mejor fragmento de código que encontré fue escrito por Stefano en esta pregunta .

Sin embargo, parece tener un error molesto al buscar términos no meta.

Aquí hay algunos detalles de mi instalación de desarrollo local. He impreso las 2 consultas de MySQL en la pantalla.

Vista de la única publicación de CPT que estoy usando para probar

Esteeselcódigoquefuncionacomoseesperabaymepermitebuscarmetadatosdesdeadmin

Lamentablemente, el código crea duplicados en coincidencias no meta, en este caso, en el título de la publicación

Unacapturaquemuestraelestadodelapublicación,eltipodepublicaciónylapublicacióndelosantepasadosdelosfalsos

! Un mensaje que muestra el estado de la publicación, el tipo de publicación y los antepasados posteriores de los duplicados.

Aquí está el código que estoy ejecutando, es básicamente el mismo que el de Stefano, pero con mis intentos crudos de hacer que la consulta funcione.

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

2 respuestas

11

Una declaración GROUP BY puede agrupar tus publicaciones después de JOIN . Para Wordpress puede usar el 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;
}
    
respondido por el epilektric 25.08.2013 - 12:20
4

Gracias por su trabajo en esto, amigos. Este código me llevó casi todo el camino, pero al usar WP 3.8 obtenía un error de tabla / alias no único de SQL, por lo que hice algunos cambios. Para que funcionara en mi configuración, tuve que establecer un alias $ wpdb- > postmeta que se usó en la declaración ÚNETE. También reviso solo una vez para ver si se deben usar los ganchos para que no se disparen siempre. Espero que esto ayude a alguien!

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

Lea otras preguntas en las etiquetas