Includere i termini della tassonomia personalizzata nella ricerca
Ho due tassonomie personalizzate applicate a due tipi di post personalizzati. L'elenco dei termini nella barra laterale funziona correttamente e mostra tutti i post associati. Tuttavia, se si cerca uno specifico termine, non vengono visualizzati i post con quel termine.
Esempio: http://dev.andrewnorcross.com/das/all-case-studies/ Cercando il termine "PQRI"
Non ottengo alcun risultato. Qualche idea? Ho provato a utilizzare vari plugin di ricerca ma questi o compromettono i miei parametri di ricerca personalizzati o semplicemente non funzionano.

Consiglierei anche il plugin Search Everything, ma se vuoi implementare questa funzionalità utilizzando la funzione di ricerca di WP, ecco il codice che sto utilizzando nel mio tema Atom:
// cerca in tutte le tassonomie, basato su: 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;
// dobbiamo raggruppare per ID del post
$groupby_id = "{$wpdb->posts}.ID";
if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;
// groupby era vuoto, usa il nostro
if(!strlen(trim($groupby))) return $groupby_id;
// non era vuoto, aggiungi il nostro
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');
È basato sul plugin Tag-Search: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23

Fantastico! Come posso modificare questo codice per escludere un array di ID di tassonomie dalla ricerca?

È importante notare che le funzioni di callback per questi hook accettano 2 argomenti; il secondo per tutti loro è l'istanza WP_Query che viene passata per riferimento. Qualsiasi controllo per is_search()
o altre chiamate ai metodi di WP_Query (is_search()
, is_home()
, ecc.) dovrebbero sempre essere chiamate direttamente sull'istanza della query (ad esempio $query->is_search()
assumendo che il nome della variabile dell'istanza sia $query
nella firma del callback) piuttosto che sulla funzione template che si riferirà sempre alla query principale, non alla query per cui il filtro è in esecuzione.

Inoltre, probabilmente non è una buona idea iniettare direttamente la stringa di ricerca pubblicamente disponibile in una query SQL... lettura consigliata

Vorrei solo aggiungere che c'è un conflitto con WPML perché WPML utilizza già 'T' nella parte di join, quindi utilizzare qualcosa di personalizzato invece di tr, tt e t risolve questo problema

@EvanMattson — hai commentato sopra che "probabilmente non è una buona idea iniettare direttamente la stringa di ricerca pubblicamente disponibile in una query SQL." Come potresti procedere per ridurre questo rischio? Ho letto il link che hai fornito ma non ho capito come si collega alla risposta originale. Grazie mille Em.

@TheChewy la risposta sopra mostra get_search_query()
utilizzato direttamente nell'istruzione MySQL della clausola WHERE. Questo codice è vulnerabile ad attacchi SQL injection, dove chiunque può eseguire query SQL arbitrarie sul tuo sito passandole attraverso il campo di ricerca. Ovviamente questo è in qualche modo il funzionamento delle ricerche, ma il punto importante è che questo input deve essere preparato correttamente per assicurarsi che venga interpretato come termini di ricerca e non come istruzioni SQL. Questo è lo scopo del metodo $wpdb->prepare()
descritto nella lettura consigliata

@TheChewy puoi anche trovare alcuni buoni esempi nella documentazione per wpdb::prepare()
qui: https://developer.wordpress.org/reference/classes/wpdb/prepare/

@EvanMattson Ciao Evan, grazie per il suggerimento. Sono nuovo sia a PHP che al codice personalizzato di WP e questa cosa mi è andata completamente oltre la testa. Saresti in grado di duplicare il codice con l'aggiunta di $wpdb->prepare()
se non è troppo difficile? Penso che ci vorranno settimane prima che riesca a capire quel genere di cose.

Questo è il sistema di ricerca standard di WordPress? Perché non sembra includere le tassonomie (nemmeno quelle standard, come categorie e tag) nella ricerca. Il codice cerca in post_title
e post_content
, ma se vuoi includere altro dovrai agganciarti al filtro posts_search
.

Ho provato la soluzione di Onetrickpony sopra https://wordpress.stackexchange.com/a/5404/37612, che è ottima, ma ho trovato un problema che non funzionava per me e farei una piccola modifica:
- se cerco una stringa nel titolo della tassonomia - funziona perfettamente
se la tassonomia contiene caratteri speciali come gli "Umlaut" tedeschi (ö,ä,ü) e si cerca oe, ae, ue invece di usare il carattere speciale - bisogna aggiungere la ricerca nello slug della tassonomia -
OR t.slug LIKE '%".get_search_query()."%'
se si cerca una combinazione di query di ricerca e filtro tassonomico - funziona anche questo bene
Ma il problema è quando si prova a usare solo il filtro tassonomico - l'hook di ricerca aggiunge una stringa vuota alla query se non si cerca del testo, e per questo motivo si ottengono TUTTI i post nei risultati, invece di solo quelli della tassonomia filtrata. Un semplice IF risolve il problema. Quindi il codice modificato sarebbe questo (funziona perfettamente per me!)
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; // dobbiamo raggruppare per ID post $groupby_id = "{$wpdb->posts}.ID"; if(!is_search() || strpos($groupby, $groupby_id) !== false || !get_search_query()) return $groupby; // groupby era vuoto, usiamo il nostro if(!strlen(trim($groupby))) return $groupby_id; // non era vuoto, aggiungiamo il nostro 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');

Ho trovato la risposta di onetrickpony molto utile, ma tratta ogni ricerca come un singolo termine e non gestisce una frase di ricerca racchiusa tra virgolette. Ho modificato il suo codice (in particolare, la funzione atom_search_where
) per gestire queste due situazioni. Ecco la mia versione modificata del suo codice:
// ricerca in tutte le tassonomie, basata su: 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"; // --- impostare a OR se si preferisce non richiedere che tutti i termini di ricerca corrispondano alle tassonomie
$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;
// è necessario raggruppare per ID del post
$groupby_id = "{$wpdb->posts}.ID";
if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;
// groupby era vuoto, usa il nostro
if(!strlen(trim($groupby))) return $groupby_id;
// non era vuoto, aggiungi il nostro
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');

Ho lo stesso livello di informazioni di Jan. So che è possibile estendere la ricerca anche con i plugin.
Probabilmente Search Everything (Plugin per WordPress) è quello che stai cercando. Secondo la lista delle funzionalità, ora supporta le tassonomie personalizzate.

Ho lo stesso problema con il plugin WooCommerce del carrello.. I miei risultati di ricerca non includono il termine della tassonomia personalizzata, 'product_tag', perché non è un tag standard del post. Ho trovato una soluzione in questo altro thread su StackOverflow riguardo la questione:
L'esempio di codice di tkelly ha funzionato per me quando ho sostituito il termine author
nel suo esempio con product_tag
in base alle nostre esigenze per i plugin del carrello.
