Includerea termenilor de taxonomie personalizată în căutare
Am două taxonomii personalizate aplicate la două tipuri de postări personalizate. Lista de termeni apare corect în bara laterală și va afișa toate postările asociate cu aceasta. Cu toate acestea, dacă cauți unul dintre termeni în mod specific, nu apare nicio postare cu acel termen.
Exemplu: http://dev.andrewnorcross.com/das/all-case-studies/ Caută termenul "PQRI"
Nu obțin niciun rezultat. Aveți vreo idee? Am încercat să folosesc diverse plugin-uri de căutare, dar fie îmi strică parametrii personalizați de căutare, fie pur și simplu nu funcționează.

Aș recomanda și plugin-ul Search Everything, dar dacă dorești să implementezi această funcționalitate folosind funcția de căutare din WordPress, iată codul pe care îl folosesc în tema mea Atom:
// caută în toate taxonomiile, bazat pe: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23
function atom_search_where($where){
global $wpdb;
if (is_search())
$where .= "OR (t.name LIKE '%".get_search_query()."%' AND {$wpdb->posts}.post_status = 'publish')";
return $where;
}
function atom_search_join($join){
global $wpdb;
if (is_search())
$join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id";
return $join;
}
function atom_search_groupby($groupby){
global $wpdb;
// trebuie să grupăm după ID-ul postării
$groupby_id = "{$wpdb->posts}.ID";
if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;
// groupby era gol, folosește varianta noastră
if(!strlen(trim($groupby))) return $groupby_id;
// nu era gol, adaugă varianta noastră
return $groupby.", ".$groupby_id;
}
add_filter('posts_where','atom_search_where');
add_filter('posts_join', 'atom_search_join');
add_filter('posts_groupby', 'atom_search_groupby');
Codul este bazat pe plugin-ul Tag-Search: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23

Este minunat – cum poate fi modificat acest cod pentru a exclude o serie de ID-uri de taxonomii din căutare?

Trebuie menționat că funcțiile de callback pentru aceste hook-uri acceptă 2 argumente; al doilea pentru toate fiind instanța WP_Query care este transmisă prin referință. Orice verificări pentru is_search()
sau alte apeluri de metode WP_Query (is_search()
, is_home()
etc.) ar trebui întotdeauna apelate direct pe instanța query-ului (de ex. $query->is_search()
presupunând că numele variabilei instanței este $query
în semnătura callback-ului) și nu prin funcția template care se va referi întotdeauna la query-ul principal, nu la query-ul pentru care rulează filtrul.

De asemenea, probabil nu este o idee bună să injectezi șirul de căutare disponibil public direct într-un query SQL... lectură recomandată

Aș dori să adaug că există un conflict cu WPML deoarece WPML folosește deja 'T' în partea de join, așa că folosirea unui nume personalizat în loc de tr, tt și t rezolvă această problemă

@EvanMattson — ai menționat mai sus că "probabil nu este o idee bună să injectezi șirul de căutare public disponibil direct într-o interogare SQL." Cum ai proceda pentru a elimina acest risc? Am citit linkul furnizat dar nu am reușit să văd legătura cu răspunsul original. Mulțumesc mult, Em.

@TheChewy răspunsul de mai sus arată get_search_query()
folosit direct în instrucțiunea MySQL a clauzei WHERE. Acest cod este vulnerabil la atacuri de tip SQL injection, unde oricine poate executa interogări SQL arbitrare pe site-ul tău trecându-le prin câmpul de căutare. Evident, într-o oarecare măsură așa funcționează căutările, dar punctul important este că această intrare trebuie pregătită corespunzător pentru a se asigura că este interpretată ca termeni de căutare și nu ca instrucțiuni SQL. Aceasta este scopul metodei $wpdb->prepare()
care este descrisă în lectura recomandată

@TheChewy poți găsi și câteva exemple bune în documentația pentru wpdb::prepare()
aici: https://developer.wordpress.org/reference/classes/wpdb/prepare/

@EvanMattson Bună Evan, mulțumesc pentru sugestie. Sunt nou atât în PHP cât și în codul personalizat WP și asta a depășit complet nivelul meu de înțelegere. Ai putea să reproduezi codul cu $wpdb->prepare()
adăugat dacă nu e prea complicat? Cred că o să-mi ia săptămâni până voi ajunge aproape să înțeleg astfel de lucruri.

Este aceasta căutarea standard din WordPress? Pentru că nu pare să includă taxonomiile (nici măcar cele standard, cum ar fi categorii și etichete) în căutare. Codul caută în post_title
și post_content
, dar dacă doriți să includeți orice altceva, ar trebui să folosiți filtrul posts_search
.

Am încercat soluția lui Onetrickpony de mai sus https://wordpress.stackexchange.com/a/5404/37612, care este excelentă, dar am găsit o problemă acolo, care nu a funcționat pentru mine, și aș face o mică modificare:
- dacă am căutat un șir în titlul taxonomiei - funcționează perfect
dacă taxonomia are caractere speciale, de exemplu cu "umlaute" germane (ö,ä,ü) și cineva caută oe, ae, ue în loc să folosească caracterele speciale - trebuie să adăugați căutarea în slug-ul taxonomiei -
OR t.slug LIKE '%".get_search_query()."%'
dacă căutați o combinație între o interogare de căutare și un filtru de taxonomie - acest lucru funcționează de asemenea bine
Dar problema apare când încercați să folosiți doar filtrul de taxonomie - hook-ul de căutare adaugă un șir gol la interogare dacă nu se caută niciun text, și din acest motiv obțineți TOATE articolele în rezultat, în loc de doar cele din taxonomia filtrată. O simplă instrucțiune IF rezolvă problema. Deci codul modificat ar fi acesta (funcționează perfect pentru mine!)
function custom_search_where($where){ global $wpdb; if (is_search() && get_search_query()) $where .= "OR ((t.name LIKE '%".get_search_query()."%' OR t.slug LIKE '%".get_search_query()."%') AND {$wpdb->posts}.post_status = 'publish')"; return $where; } function custom_search_join($join){ global $wpdb; if (is_search()&& get_search_query()) $join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id"; return $join; } function custom_search_groupby($groupby){ global $wpdb; // trebuie să grupăm după ID-ul articolului $groupby_id = "{$wpdb->posts}.ID"; if(!is_search() || strpos($groupby, $groupby_id) !== false || !get_search_query()) return $groupby; // groupby era gol, folosim al nostru if(!strlen(trim($groupby))) return $groupby_id; // nu era gol, adăugăm al nostru return $groupby.", ".$groupby_id; } add_filter('posts_where','custom_search_where'); add_filter('posts_join', 'custom_search_join'); add_filter('posts_groupby', 'custom_search_groupby');

Am găsit răspunsul de la onetrickpony foarte bun, dar acesta tratează orice căutare ca un singur termen și nu gestionează fraze de căutare închise între ghilimele. Am modificat puțin codul său (mai exact, funcția atom_search_where
) pentru a gestiona aceste două situații. Iată versiunea mea modificată a codului său:
// caută în toate taxonomiile, bazat pe: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23
function atom_search_where($where){
global $wpdb, $wp_query;
if (is_search()) {
$search_terms = get_query_var( 'search_terms' );
$where .= " OR (";
$i = 0;
foreach ($search_terms as $search_term) {
$i++;
if ($i>1) $where .= " AND"; // --- schimbă în OR dacă preferi să nu fie necesar ca toți termenii să se potrivească în taxonomii
$where .= " (t.name LIKE '%".$search_term."%')";
}
$where .= " AND {$wpdb->posts}.post_status = 'publish')";
}
return $where;
}
function atom_search_join($join){
global $wpdb;
if (is_search())
$join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id";
return $join;
}
function atom_search_groupby($groupby){
global $wpdb;
// trebuie să grupăm după ID-ul postării
$groupby_id = "{$wpdb->posts}.ID";
if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;
// groupby era gol, folosește al nostru
if(!strlen(trim($groupby))) return $groupby_id;
// nu era gol, adaugă al nostru
return $groupby.", ".$groupby_id;
}
add_filter('posts_where','atom_search_where');
add_filter('posts_join', 'atom_search_join');
add_filter('posts_groupby', 'atom_search_groupby');

Am aceeași nivel de informații ca Jan. Știu că este posibil să extindeți căutarea și cu plugin-uri.
Probabil Search Everything (Wordpress Plugin) este ceea ce cauți. Conform listei de funcționalități, acum suportă taxonomii personalizate.

Am aceeași problemă cu plugin-ul WooCommerce pentru coș.. Rezultatele mele de căutare nu includ termenul din taxonomia personalizată, 'product_tag', deoarece nu este un tag standard de postare. Am găsit o soluție în acest alt thread de pe StackOverflow despre această problemă:
Exemplul de cod oferit de tkelly a funcționat pentru mine atunci când am înlocuit termenul author
din exemplul său cu product_tag
conform necesităților noastre pentru plugin-urile de coș.
