Questa soluzione filtra le stringhe di ricerca applicando un'espressione regolare che corrisponde solo ai caratteri degli script Unicode comuni e latini.
Corrispondenza di caratteri latini con espressioni regolari
Ho appena fatto esplodere la mia mente a Stack Overflow . A quanto pare, le espressioni regolari hanno un meccanismo per abbinare intere categorie Unicode, inclusi i valori per specificare interi "script" Unicode , ciascuno corrispondente a gruppi di caratteri utilizzati in diversi sistemi di scrittura.
Questo viene fatto utilizzando il \p
meta-carattere seguito da un identificatore di categoria Unicode tra parentesi graffe - quindi [\p{Common}\p{Latin}]
corrisponde a un singolo carattere negli script latino o comune - questo include punteggiatura, numeri e simboli vari.
Come sottolinea Biron 'Sparrow Hawk' di @Paul , il u
flag modificatore di pattern dovrebbe essere impostato alla fine dell'espressione regolare affinché le funzioni PCRE di PHP trattino la stringa di soggetti come UTF-8
codificata Unicode.
Tutti insieme, quindi, il modello
/^[\p{Latin}\p{Common}]+$/u
corrisponderà a un'intera stringa composta da uno o più caratteri negli script Latin e Common Unicode.
Filtro della stringa di ricerca
Un buon posto per intercettare una stringa di ricerca è l' pre_get_posts
azione che si attiva immediatamente prima che WordPress esegua la query. Con più attenzione , questo potrebbe anche essere realizzato usando un request
filtro .
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[\p{Latin}\p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
// If execution reaches this point, the search string contains non-Latin characters
//TODO: Handle non-Latin search strings
//TODO: Set up logic to display error message
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
Risposta a ricerche non consentite
Una volta stabilito che una stringa di ricerca contiene caratteri non latini, è possibile utilizzare WP_Query::set()
per modificare la query modificandone il nome chiamato query - influenzando così la query SQL che WordPress successivamente compone ed esegue.
Le variabili di query più rilevanti sono probabilmente le seguenti:
s
è la variabile di query corrispondente a una stringa di ricerca. L'impostazione su null
o una stringa vuota ( ''
) comporterà che WordPress non considera più la query come una ricerca - spesso questo porta a un modello di archivio che mostra tutti i post o la prima pagina del sito, a seconda dei valori dell'altro query var. Impostandolo su un singolo spazio ( ' '
), tuttavia, WordPress lo riconoscerà come una ricerca e quindi tenterà di visualizzare il search.php
modello.
page_id
potrebbe essere utilizzato per indirizzare l'utente a una pagina specifica di tua scelta.
post__in
può limitare la query a una selezione specifica di post. Impostandolo su un array con un ID post impossibile, può servire come misura per garantire che la query non restituisca assolutamente nulla .
Quanto sopra in mente, potresti fare quanto segue per rispondere a una cattiva ricerca caricando il search.php
modello senza risultati:
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[\p{Latin}\p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
$query->set( 's', ' ' ); // Replace the non-latin search with an empty one
$query->set( 'post__in', array(0) ); // Make sure no post is ever returned
//TODO: Set up logic to display error message
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
Visualizzazione di un errore
Il modo in cui visualizzi effettivamente il messaggio di errore dipende fortemente dalla tua applicazione e dalle capacità del tuo tema: ci sono molti modi per farlo. Se il tuo tema chiama get_search_form()
nel suo modello di ricerca, la soluzione più semplice è probabilmente quella di utilizzare un hook di pre_get_search_form
azione per generare l'errore immediatamente sopra il modulo di ricerca:
function wpse261038_validate_search_characters( $query ) {
// Leave admin, non-main query, and non-search queries alone
if( is_admin() || !$query->is_main_query() || !$query->is_seach() )
return;
// Check if the search string contains only Latin/Common Unicode characters
$match_result = preg_match( '/^[\p{Latin}\p{Common}]+$/u', $query->get( 's' ) );
// If the search string only contains Latin/Common characters, let it continue
if( 1 === $match_result )
return;
$query->set( 's', ' ' ); // Replace the non-latin search with an empty one
$query->set( 'post__in', array(0) ); // Make sure no post is ever returned
add_action( 'pre_get_search_form', 'wpse261038_display_search_error' );
}
add_action( 'pre_get_posts', 'wpse261038_validate_search_characters' );
function wpse261038_display_search_error() {
echo '<div class="notice notice-error"><p>Your search could not be completed as it contains characters from non-Latin alphabets.<p></div>';
}
Alcune altre possibilità per visualizzare un messaggio di errore includono:
- Se il tuo sito utilizza JavaScript che può visualizzare messaggi "flash" o "modali" (o aggiungi tali abilità da solo), aggiungi ad esso la logica per visualizzare i messaggi al caricamento della pagina quando viene impostata una variabile specifica, quindi aggiungi un
wp_enqueue_script
hook con un valore $priority
maggiore di quello che accoda quel JavaScript e usa wp_localize_script()
per impostare quella variabile in modo da includere il tuo messaggio di errore.
- Utilizzare
wp_redirect()
per inviare l'utente all'URL desiderato (questo metodo richiede un caricamento di pagina aggiuntivo).
- Imposta una variabile PHP o invoca un metodo che informerà il tuo tema / plugin sull'errore in modo che possa visualizzarlo dove appropriato.
- Impostare la
s
variabile di query su ''
invece di ' '
e utilizzare page_id
al posto di post__in
per restituire una pagina di propria scelta.
- Usa un
loop_start
hook per iniettare un WP_Post
oggetto falso contenente il tuo errore nei risultati della query: questo è sicuramente un brutto hack e potrebbe non sembrare giusto con il tuo tema particolare, ma ha l'effetto collaterale potenzialmente desiderabile di sopprimere il messaggio "Nessun risultato".
- Utilizzare un
template_include
hook di filtro per scambiare il modello di ricerca con uno personalizzato nel tema o nel plug-in che visualizza l'errore.
Senza esaminare il tema in questione, è difficile determinare quale percorso si dovrebbe prendere.