Come posso migliorare questo frammento di query di amministrazione per evitare di generare risultati duplicati su ricerche non meta?


11

Ho giocato con frammenti di codice che aggiungono metadati alle ricerche dell'amministratore.

Il miglior frammento che ho trovato è stato scritto da Stefano su questa domanda .

Tuttavia, sembra avere 1, fastidioso bug durante la ricerca di termini non meta.

Ecco alcuni suggerimenti dalla mia installazione di sviluppo locale. Ho stampato le 2 query MySQL sullo schermo.

Visualizzazione del singolo post CPT che sto usando per testare

Visualizzazione del singolo post CPT che sto usando per testare

Questo è il codice che funziona come previsto e mi consente di cercare metadati dall'amministratore

Questo è il codice che funziona come previsto e mi consente di cercare metadati dall'amministratore

Sfortunatamente il codice crea duplicati su corrispondenze non meta, in questo caso sul titolo del post

Sfortunatamente il codice crea duplicati su corrispondenze non meta, in questo caso sul titolo del post

Una presa che mostra lo stato della posta, il tipo di posta e gli antenati dei duplicati

! Una presa che mostra lo stato della posta, il tipo di posta e gli antenati dei duplicati

Ecco il codice che sto eseguendo, è sostanzialmente lo stesso di Stefano, ma con i miei rozzi tentativi di far funzionare la query.

/*
 * 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' );  

Forse elenca anche le revisioni?
passatgt

Pensavo di guardare solo i libri pubblicati, perché ho rimosso in sospeso, privato, bozza e futuro. Non ho notato un tipo di revisione.
jnthnclrk,

Hmmm, non sembra essere uno stato di "revisione": codex.wordpress.org/Post_Status
jnthnclrk

prova a stampare_r il tipo di post o l'id del post in una delle colonne, penso che le revisioni siano tipi di post, quindi se riesci a vedere le revisioni, lo hai anche nei risultati. Ma posso anche vedere che visualizzi solo i risultati dal tipo di post delle inserzioni, quindi penso di sbagliarmi. Ma vale la pena provare :)
passatgt

Aggiunto un nuovo grab con stati dei post, tipi di post e antenati.
jnthnclrk,

Risposte:


11

Una GROUP BYdichiarazione può raggruppare i tuoi post dopo il JOIN. Per Wordpress è possibile utilizzare il posts_groupbyfiltro.

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

Grazie per il tuo lavoro su questo, gente. Questo codice mi ha portato quasi ovunque, ma usando WP 3.8 stavo ottenendo un errore alias / tabella non univoco SQL, quindi ho apportato alcune modifiche. Perché funzioni sul mio setup ho dovuto impostare un alias $ wpdb-> postmeta che è stato usato nell'istruzione JOIN. Inoltre controllo solo una volta per vedere se i ganci dovrebbero essere usati in modo che non sparino ogni volta. Spero che questo aiuti qualcuno!

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.