To rozwiązanie filtruje ciągi wyszukiwania, stosując wyrażenie regularne, które pasuje tylko do znaków ze skryptów Unicode Common i Latin.
Dopasowywanie znaków łacińskich do wyrażeń regularnych
Właśnie przeleciał mi umysł w Stack Overflow . Jak się okazuje, wyrażenia regularne mają mechanizm dopasowywania całych kategorii Unicode, w tym wartości określających całe „skrypty” Unicode , z których każdy odpowiada grupom znaków używanych w różnych systemach pisania.
Odbywa się to za pomocą \p
meta-znaku, po którym następuje nawias identyfikujący kategorię Unicode w nawiasach klamrowych - więc [\p{Common}\p{Latin}]
pasuje do pojedynczego znaku w skrypcie łacińskim lub wspólnym - obejmuje to znaki interpunkcyjne, cyfry i różne symbole.
Jak wskazuje @Paul „Sparrow Hawk” Biron , u
flaga modyfikatora wzorca powinna być ustawiona na końcu wyrażenia regularnego, aby funkcje PCRE PHP mogły traktować ciąg znaków jako UTF-8
kodowany w Unicode.
Wszystko razem więc wzór
/^[\p{Latin}\p{Common}]+$/u
dopasuje cały ciąg złożony z jednego lub więcej znaków w skryptach Latin i Common Unicode.
Filtrowanie wyszukiwanego ciągu
Dobrym miejscem do przechwytywania ciąg wyszukiwania jest działanie jak pożary bezpośrednio przed WordPress wykonuje zapytanie. Z większą ostrożnością można to również osiągnąć za pomocą filtra .pre_get_posts
request
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' );
Reagowanie na niedozwolone wyszukiwania
Po ustaleniu, że ciąg wyszukiwania zawiera znaki spoza alfabetu łacińskiego, możesz użyć go WP_Query::set()
do zmodyfikowania zapytania poprzez zmianę jego nazwanych zmiennych zapytania - wpływając w ten sposób na zapytanie SQL, które WordPress następnie tworzy i wykonuje.
Najbardziej odpowiednie zmienne zapytania są prawdopodobnie następujące:
s
jest zmienną zapytania odpowiadającą wyszukiwanemu ciągowi. Ustawienie go na null
lub pusty ciąg znaków ( ''
) spowoduje, że WordPress przestanie traktować zapytanie jako wyszukiwanie - często powoduje to, że szablon archiwum wyświetla wszystkie posty lub stronę główną witryny, w zależności od wartości innych zapytania zmienne. Ustawienie go na pojedynczą spację ( ' '
) spowoduje jednak, że WordPress rozpozna go jako wyszukiwanie, a zatem spróbuje wyświetlić search.php
szablon.
page_id
może zostać wykorzystany do przekierowania użytkownika na wybraną stronę.
post__in
może ograniczyć zapytanie do określonego wyboru postów. Ustawienie go na tablicę z niemożliwym identyfikatorem postu może służyć jako miara zapewniająca, że zapytanie nie zwróci absolutnie niczego .
Mając powyższe na uwadze, możesz wykonać następujące czynności, aby odpowiedzieć na złe wyszukiwanie, ładując search.php
szablon bez wyników:
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' );
Wyświetlanie błędu
Sposób, w jaki faktycznie wyświetlasz komunikat o błędzie, zależy w dużej mierze od Twojej aplikacji i możliwości motywu - można to zrobić na wiele sposobów. Jeśli motyw wywołuje się get_search_form()
w szablonie wyszukiwania, najłatwiejszym rozwiązaniem jest prawdopodobnie użycie haka do pre_get_search_form
działania, aby wyświetlić błąd bezpośrednio nad formularzem wyszukiwania:
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>';
}
Niektóre inne możliwości wyświetlania komunikatu o błędzie obejmują:
- Jeśli Twoja strona korzysta z JavaScript, który może wyświetlać komunikaty „flash” lub „modalne” (lub dodajesz takie możliwości samodzielnie), dodaj logikę do wyświetlania komunikatów przy ładowaniu strony, gdy ustawiona jest określona zmienna, a następnie dodaj
wp_enqueue_script
haczyk z $priority
większym niż ten, który kolejkuje ten JavaScript, i użyj, wp_localize_script()
aby ustawić tę zmienną tak, aby zawierała komunikat o błędzie.
- Służy
wp_redirect()
do wysyłania użytkownika na wybrany adres URL (ta metoda wymaga dodatkowego ładowania strony).
- Ustaw zmienną PHP lub wywołaj metodę, która poinformuje twoją kompozycję / wtyczkę o błędzie, tak aby wyświetlał ją w razie potrzeby.
- Ustaw
s
zmienną zapytania na ''
zamiast ' '
i użyj page_id
zamiast post__in
, aby zwrócić wybraną stronę.
- Użyj
loop_start
haka, aby wstrzyknąć fałszywy WP_Post
obiekt zawierający błąd do wyników zapytania - jest to zdecydowanie brzydki hack i może nie wyglądać dobrze z określonym motywem, ale ma potencjalnie pożądany efekt uboczny polegający na pomijaniu komunikatu „Brak wyników”.
- Użyj
template_include
haka filtru, aby zamienić szablon wyszukiwania na niestandardowy w motywie lub wtyczce, który wyświetla błąd.
Bez zbadania omawianego tematu trudno jest ustalić, którą trasę należy obrać.