Comment puis-je améliorer cet extrait de requête d'administrateur pour éviter de générer des résultats en double sur des recherches non méta?

11

J'ai joué avec des extraits de code qui ajoutent des métadonnées aux recherches de l'administrateur.

Le meilleur extrait que j'ai trouvé a été écrit par Stefano sur cette question .

Cependant, il semble y avoir un bug gênant lors de la recherche de termes non méta.

Voici quelques captures de mon installation de développeur local. J'ai imprimé les 2 requêtes MySQL à l'écran.

Vue de la publication simple que j'utilise pour tester

C’estlecodequifonctionnecommeprévuetmepermetderechercherdesmétadonnéesàpartirdel’administrateur

Malheureusement, le code crée des doublons sur les correspondances non méta, dans ce cas sur le titre du post

Unecaptureindiquantlestatutdelapublication,letypedepublicationetlesancêtresdepublicationdesdupes

! Une capture indiquant le statut de la publication, le type de publication et les ancêtres de publication des dupes

Voici le code que je lance, il est fondamentalement le même que celui de Stefano, mais avec mes tentatives brutes de faire en sorte que la requête fonctionne.

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

2 réponses

11

Un relevé GROUP BY peut regrouper vos publications après le JOIN . Pour Wordpress, vous pouvez utiliser le filtre 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;
}
    
réponse donnée epilektric 25.08.2013 - 12:20
4

Merci pour votre travail, chers collègues. Ce code m'a permis de faire presque tout le chemin, mais avec WP 3.8, j'avais une erreur SQL non unique de table / alias, j'ai donc apporté quelques modifications. Pour que cela fonctionne sur ma configuration, je devais définir un alias $ wpdb- > postmeta utilisé dans l'instruction JOIN. Je vérifie également une seule vérification pour voir si les crochets doivent être utilisés afin qu'ils ne tirent pas à chaque fois. J'espère que cela aide quelqu'un!

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
    
réponse donnée souverian 30.12.2013 - 19:47

Lire d'autres questions sur les étiquettes