Extinderea contextului de căutare în ecranul listei de postări din admin

11 mar. 2011, 14:09:59
Vizualizări: 39.8K
Voturi: 52

Am creat un tip de postare personalizat și i-am atașat câteva câmpuri personalizate. Acum aș dori ca funcția de căutare pe care autorii o pot efectua în ecranul listei de postări personalizate (în panoul de administrare) să fie executată și pe câmpurile meta și nu doar să caute în titlu și conținut ca de obicei.

Unde pot să mă conectez și ce cod trebuie să folosesc?

Imagine exemplu Exemplu de căutare în panoul de administrare WordPress

Stefano

2
Comentarii

O întrebare veche, dar... aș dori să sugerez ascunderea adreselor de email și a numelor din capturile de ecran...

Erenor Paz Erenor Paz
22 iul. 2018 23:16:45

https://wordpress.stackexchange.com/a/317393/133699

Muhammad Bilal Muhammad Bilal
15 apr. 2023 08:33:15
Toate răspunsurile la întrebare 6
5
49

Am rezolvat filtrarea interogării prin adăugarea unei alături pe tabelul postmeta și modificarea clauzei WHERE. Sfaturi despre filtrarea clauzei WHERE (adesea necesită căutare și înlocuire cu expresii regulate) sunt aici pe codex:

add_filter( 'posts_join', 'segnalazioni_search_join' );
function segnalazioni_search_join ( $join ) {
    global $pagenow, $wpdb;

    // Vreau ca filtrul să se aplice doar când se efectuează o căutare pe pagina de editare a Tipului de Postare Personalizat numit "segnalazioni".
    if ( is_admin() && 'edit.php' === $pagenow && 'segnalazioni' === $_GET['post_type'] && ! empty( $_GET['s'] ) ) {    
        $join .= 'LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }
    return $join;
}

add_filter( 'posts_where', 'segnalazioni_search_where' );
function segnalazioni_search_where( $where ) {
    global $pagenow, $wpdb;

    // Vreau ca filtrul să se aplice doar când se efectuează o căutare pe pagina de editare a Tipului de Postare Personalizat numit "segnalazioni".
    if ( is_admin() && 'edit.php' === $pagenow && 'segnalazioni' === $_GET['post_type'] && ! empty( $_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.= " GROUP BY {$wpdb->posts}.id"; // Rezolvă rezultatele duplicate
    }
    return $where;
}
18 mar. 2011 11:02:17
Comentarii

Uau! Exact ce căutam. Totuși, cred că am găsit un bug - când caut după titlul articolului, primesc un rezultat care apoi este duplicat de 5 ori în rezultate!?! http://imgur.com/eE52gIA

jnthnclrk jnthnclrk
22 aug. 2013 17:58:07

Iată un alt screenshot cu SQL-ul afișat: http://tinypic.com/view.php?pic=124tqb6&s=5 Nu înțeleg de ce primesc 5 rezultate!?!

jnthnclrk jnthnclrk
22 aug. 2013 23:19:45

Am postat o întrebare separată despre repararea bug-ului cu duplicatele: http://wordpress.stackexchange.com/questions/111185/how-do-i-improve-this-admin-query-snippet-to-avoid-generating-duplicate-results

jnthnclrk jnthnclrk
24 aug. 2013 14:47:01

Acest post și cel de mai jos mi-au fost utile. Acum trebuie să găsesc o modalitate de a include căutarea după autorul postării și de a afișa postările realizate de acesta.

Shawn Rebelo Shawn Rebelo
31 iul. 2018 21:27:38

@Stefano, rezultatele căutării funcționează. Am o problemă, câmpul implicit „Titlul postării” afișează în mod repetat același rezultat în partea de administrare. Vezi:https://imgur.com/a/W4wmXhO

Muhammad Bilal Muhammad Bilal
23 oct. 2018 12:16:24
0
14

Răspunsul lui Stefano este foarte bun, dar îi lipsește o clauză distinctă:

function segnalazioni_search_distinct( $where ){
    global $pagenow, $wpdb;

    if ( is_admin() && $pagenow=='edit.php' && $_GET['post_type']=='segnalazioni' && $_GET['s'] != '') {
    return "DISTINCT";

    }
    return $where;
}
add_filter( 'posts_distinct', 'segnalazioni_search_distinct' );

Adaugă codul de mai sus, actualizează-l și va funcționa fără duplicate.

30 apr. 2014 15:00:25
6

Acest lucru va funcționa,

function custom_search_query( $query ) {
    $custom_fields = array(
        // aici se introduc toate câmpurile meta în care doriți să căutați
        "rg_first_name",
        "rg_1job_designation"
    );
    $searchterm = $query->query_vars['s'];

    // trebuie să eliminăm parametrul "s" din interogare, deoarece va împiedica găsirea postărilor
    $query->query_vars['s'] = "";

    if ($searchterm != "") {
        $meta_query = array('relation' => 'OR');
        foreach($custom_fields as $cf) {
            array_push($meta_query, array(
                'key' => $cf,
                'value' => $searchterm,
                'compare' => 'LIKE'
            ));
        }
        $query->set("meta_query", $meta_query);
    };
}
add_filter( "pre_get_posts", "custom_search_query");
31 ian. 2014 13:00:33
Comentarii

Te rog să indentăm codul corect și să incluzi o explicație despre de ce și cum acest lucru va funcționa.

tfrommen tfrommen
31 ian. 2014 13:28:45

Deși inițial am dat un vot pozitiv, am realizat că, din păcate, acest lucru va funcționa la fel pentru fiecare căutare și ar putea afecta căutarea pe partea de front-end.

Maciej Paprocki Maciej Paprocki
13 iun. 2018 16:01:23

Adăugarea unei verificări if ( $query->query['post_type'] != 'your_custom_post_type' ){ return; } la începutul funcției va împiedica rularea acesteia pe alte căutări. Reține că tehnica din acest răspuns nu mai caută în post_title, iar readăugarea acestei funcționalități nu este trivială.

jwinn jwinn
30 nov. 2018 20:21:32

Încă o problemă - Indicatorul Rezultatele căutării pentru „<cuvânt cheie>” apelează get_search_query() care la rândul său apelează get_query_var( 's' ). Deoarece "s" este setat la șir gol, Rezultatele căutării pentru „” va avea întotdeauna o valoare goală între ghilimele. Există vreo modificare la această soluție care să rezolve această problemă?

jschrab jschrab
29 ian. 2019 23:01:10

O altă problemă, această soluție va funcționa doar pentru valorile meta acum. Căutările după titlu, de exemplu, nu vor funcționa.

Ravi Mattar Ravi Mattar
16 iun. 2022 19:50:28

Răspunsul lui 'Seyed Abbas' este mai bun: caută atât în câmpul meta personalizat, cât și în titlu!

gtamborero gtamborero
21 ian. 2023 20:17:38
Arată celelalte 1 comentarii
0

Soluția 1: Adăugați acest cod în fișierul de funcții și modificați/adăugați mai multe nume de coloane pe care le-ați folosit în tipul de postare personalizat

function extend_admin_search( $query ) {

    // folosiți tipul vostru de postare
    $post_type = 'document';
    // Folosiți câmpurile/coloanele personalizate pentru căutare
    $custom_fields = array(
        "_file_name",
    );

    if( ! is_admin() )
        return;
    
    if ( $query->query['post_type'] != $post_type )
        return;

    $search_term = $query->query_vars['s'];

    // Setați la gol, altfel nu va găsi nimic
    $query->query_vars['s'] = '';

    if ( $search_term != '' ) {
        $meta_query = array( 'relation' => 'OR' );

        foreach( $custom_fields as $custom_field ) {
            array_push( $meta_query, array(
                'key' => $custom_field,
                'value' => $search_term,
                'compare' => 'LIKE'
            ));
        }

        $query->set( 'meta_query', $meta_query );
    };
}

add_action( 'pre_get_posts', 'extend_admin_search' );

Soluția 2: (Recomandat) Folosiți acest cod în fișierul de funcții fără nicio modificare

function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $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 );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );
23 oct. 2018 15:45:54
2

Cu acest cod poți căuta în lista de articole din Panoul de Administrare WordPress folosind valorile meta personalizate ale postărilor, împreună cu titlul și alte câmpuri implicite.

Te rugăm să adaugi codul de mai jos în fișierul functions.php:

if (!function_exists('extend_admin_search')) {
    add_action('admin_init', 'extend_admin_search');

    /**
     * conectează căutarea postărilor dacă suntem pe pagina de administrare pentru tipul nostru
     */
    function extend_admin_search() {
        global $typenow;

        if ($typenow === 'your_custom_post_type') {
            add_filter('posts_search', 'posts_search_custom_post_type', 10, 2);
        }
    }

    /**
     * adaugă condiție de interogare pentru meta personalizate
     * @param string $search șirul de căutare până acum
     * @param WP_Query $query
     * @return string
     */
    function posts_search_custom_post_type($search, $query) {
        global $wpdb;

        if ($query->is_main_query() && !empty($query->query['s'])) {
            $sql    = "
            or exists (
                select * from {$wpdb->postmeta} where post_id={$wpdb->posts}.ID
                and meta_key in ('custom_field1','custom_field2')
                and meta_value like %s
            )
        ";
            $like   = '%' . $wpdb->esc_like($query->query['s']) . '%';
            $search = preg_replace("#\({$wpdb->posts}.post_title LIKE [^)]+\)\K#",
                $wpdb->prepare($sql, $like), $search);
        }

        return $search;
    }
}
21 ian. 2020 10:54:44
Comentarii

Te rog să nu copiezi răspunsul tău la fiecare întrebare similară. Odată ce vei avea reputație suficientă, vei putea comenta pe orice postare și să oferi un link către răspunsul tău.

nmr nmr
21 ian. 2020 13:13:45

Am încercat să ajut pe toată lumea cu probleme similare și am muncit din greu să găsesc răspunsul corect.

Seyed Abbas Seyedi Seyed Abbas Seyedi
22 ian. 2020 13:24:45
0

Versiunea codului prezentată în câteva răspunsuri, care modifică parametrul meta_query al WP_Query în pre_get_posts, nu mai căuta în post_title. Adăugarea capacității de a căuta fie în titlul postării, fie în valorile meta, nu poate fi realizată direct în WP_Query fără modificarea SQL, din păcate, așa cum este explicat în această întrebare: Utilizarea meta query ('meta_query') cu un query de căutare ('s')

Am combinat câteva dintre tehnicile prezentate pentru a obține o versiune funcțională care evită preg_replaces și prea multe modificări SQL (aș fi dorit să le evit complet). Singurul dezavantaj este că după o căutare, textul subtitlului din partea de sus a paginii afișează "Rezultatele căutării pentru ''". Am ascuns acest text cu CSS pentru tipul meu personalizat de post.

/**
 * Extinde căutarea pentru tipul personalizat de post pentru a căuta și în câmpurile meta
 * @param  WP_Query $query
 */
function extend_cpt_admin_search( $query ) {
  // Asigură-te că suntem în zona de administrare și că acesta este tipul nostru personalizat de post
  if ( !is_admin() || $query->query['post_type'] != 'your_custom_post_type' ){
    return;
  }

  // Adaugă aici toate câmpurile meta pe care dorești să le incluzi în căutare
  $custom_fields = array(
    "your_custom_meta_field",
    "your_custom_meta_field2",
    "your_custom_meta_field3"
  );
  // Șirul de caractere introdus prin formularul de căutare
  $searchterm = $query->query_vars['s'];

  // Setează la gol, altfel nu vor fi returnate rezultate.
  // Singurul dezavantaj este că textul afișat al căutării este gol în partea de sus a paginii.
  $query->query_vars['s'] = '';

  if ($searchterm != ""){
    // Adaugă parametrul meta_query suplimentar la obiectul WP_Query.
    // Referință: https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
    $meta_query = array();
    foreach($custom_fields as $cf) {
      array_push($meta_query, array(
        'key' => $cf,
        'value' => $searchterm,
        'compare' => 'LIKE'
      ));
    }
    // Utilizează o comparație 'OR' pentru fiecare câmp meta personalizat suplimentar.
    if (count($meta_query) > 1){
      $meta_query['relation'] = 'OR';
    }
    // Setează parametrul meta_query
    $query->set('meta_query', $meta_query);


    // Pentru a permite căutării să returneze și rezultate "OR" pe post_title
    $query->set('_meta_or_title', $searchterm);
  }
}
add_action('pre_get_posts', 'extend_cpt_admin_search');
30 nov. 2018 21:19:21