Diese Lösung filtert Suchzeichenfolgen, indem ein regulärer Ausdruck angewendet wird, der nur mit Zeichen aus den allgemeinen und lateinischen Unicode-Skripten übereinstimmt.
Übereinstimmende lateinische Zeichen mit regulären Ausdrücken
Ich hatte gerade meinen Verstand bei Stack Overflow umgehauen . Wie sich herausstellt, verfügen reguläre Ausdrücke über einen Mechanismus zum Abgleichen ganzer Unicode-Kategorien, einschließlich Werten zum Angeben ganzer Unicode- "Skripte" , die jeweils Gruppen von Zeichen entsprechen, die in verschiedenen Schriftsystemen verwendet werden.
Dies erfolgt mithilfe des \p
Metazeichens, gefolgt von einer Unicode-Kategorie-ID in geschweiften Klammern - entspricht also [\p{Common}\p{Latin}]
einem einzelnen Zeichen in der lateinischen oder der allgemeinen Schrift - dies umfasst Interpunktion, Ziffern und verschiedene Symbole.
Wie @ Paul ‚Sperber‘ Biron weist darauf hin , das u
Muster Modifikator - Flag sollte am Ende des regulären Ausdrucks , um die PHP-PCRE Funktionen eingestellt werden , um die Zeichenkette zu behandeln , als UTF-8
Unicode codiert.
Alles in allem also das Muster
/^[\p{Latin}\p{Common}]+$/u
stimmt mit einer gesamten Zeichenfolge überein, die aus einem oder mehreren Zeichen in den Skripten Latin und Common Unicode besteht.
Filtern der Suchzeichenfolge
Ein guter Ort, um eine Suchzeichenfolge abzufangen, ist die pre_get_posts
Aktion , die unmittelbar vor der Ausführung der Abfrage durch WordPress ausgelöst wird. Mit größerer Sorgfalt könnte dies auch unter Verwendung eines request
Filters erreicht werden .
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' );
Antworten auf nicht zugelassene Suchvorgänge
Sobald festgestellt wurde, dass eine Suchzeichenfolge nicht-lateinische Zeichen enthält, können Sie WP_Query::set()
die Abfrage ändern, indem Sie die benannten Abfragevariablen ändern. Dies wirkt sich auf die SQL-Abfrage aus, die WordPress anschließend erstellt und ausführt.
Die relevantesten Abfragevariablen sind wahrscheinlich die folgenden:
s
ist die Abfragevariable, die einer Suchzeichenfolge entspricht. Wenn Sie es auf null
oder eine leere Zeichenfolge ( ''
) setzen, behandelt WordPress die Abfrage nicht mehr als Suche. Oft führt dies zu einer Archivvorlage, in der alle Beiträge oder die Startseite der Site angezeigt werden, abhängig von den Werten der anderen Abfrage vars. Wenn Sie es jedoch auf ein einzelnes Leerzeichen ( ' '
) setzen, erkennt WordPress es als Suche und versucht daher, die search.php
Vorlage anzuzeigen .
page_id
kann verwendet werden, um den Benutzer auf eine bestimmte Seite Ihrer Wahl zu leiten.
post__in
kann die Abfrage auf eine bestimmte Auswahl von Beiträgen beschränken. Durch Festlegen eines Arrays mit einer unmöglichen Post-ID kann es als Maß dafür dienen, dass die Abfrage absolut nichts zurückgibt .
Vor diesem Hintergrund können Sie Folgendes tun, um auf eine fehlerhafte Suche zu reagieren, indem Sie die search.php
Vorlage ohne Ergebnisse laden :
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' );
Fehler anzeigen
Die Art und Weise, wie Sie die Fehlermeldung tatsächlich anzeigen, hängt stark von Ihrer Anwendung und den Fähigkeiten Ihres Themas ab. Es gibt viele Möglichkeiten, wie dies getan werden kann. Wenn Ihr Thema die Suchvorlage aufruft get_search_form()
, besteht die einfachste Lösung wahrscheinlich darin, einen pre_get_search_form
Aktions- Hook zu verwenden, um Ihren Fehler direkt über dem Suchformular auszugeben:
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>';
}
Einige andere Möglichkeiten zum Anzeigen einer Fehlermeldung sind:
- Wenn Ihre Site JavaScript verwendet, das "Flash" - oder "Modal" -Nachrichten anzeigen kann (oder Sie solche Fähigkeiten selbst hinzufügen), fügen Sie die Logik hinzu, um Nachrichten beim Laden der Seite anzuzeigen, wenn eine bestimmte Variable festgelegt ist, und fügen Sie dann einen
wp_enqueue_script
Hook hinzu mit einem $priority
größeren Wert als dem, der das JavaScript in die Warteschlange stellt, und verwenden Sie wp_localize_script()
diese Variable, um Ihre Fehlermeldung einzuschließen .
- Verwenden Sie
wp_redirect()
diese Option , um den Benutzer an die URL Ihrer Wahl zu senden (diese Methode erfordert ein zusätzliches Laden der Seite).
- Legen Sie eine PHP-Variable fest oder rufen Sie eine Methode auf, die Ihr Thema / Plugin über den Fehler informiert, sodass es gegebenenfalls angezeigt wird.
- Setzen Sie die
s
Abfragevariable auf ''
anstelle von ' '
und verwenden Sie sie page_id
anstelle von post__in
, um eine Seite Ihrer Wahl zurückzugeben.
- Verwenden Sie einen
loop_start
Hook , um ein gefälschtes WP_Post
Objekt, das Ihren Fehler enthält, in die Abfrageergebnisse einzufügen. Dies ist definitiv ein hässlicher Hack und sieht mit Ihrem speziellen Thema möglicherweise nicht richtig aus, hat jedoch den potenziell wünschenswerten Nebeneffekt, dass die Meldung "Keine Ergebnisse" unterdrückt wird.
- Verwenden Sie einen
template_include
Filter-Hook, um die Suchvorlage gegen eine benutzerdefinierte in Ihrem Design oder Plugin auszutauschen, die Ihren Fehler anzeigt.
Ohne das betreffende Thema zu untersuchen, ist es schwierig zu bestimmen, welchen Weg Sie einschlagen sollten.