Esta solución filtra las cadenas de búsqueda aplicando una expresión regular que solo coincide con los caracteres de los scripts Common y Latin Unicode.
Relacionar caracteres latinos con expresiones regulares
Simplemente me voló la cabeza en Stack Overflow . Como resultado, las expresiones regulares tienen un mecanismo para unir categorías Unicode completas, incluidos valores para especificar "scripts" Unicode completos , cada uno correspondiente a grupos de caracteres utilizados en diferentes sistemas de escritura.
Esto se realiza mediante el uso de \p
metacaracteres seguido de un identificador de categoría Unicode entre llaves, por lo que [\p{Common}\p{Latin}]
coincide con un solo carácter en los guiones latinos o comunes , esto incluye signos de puntuación, números y símbolos misceláneos.
Como señala @Paul 'Sparrow Hawk' Biron , el u
indicador del modificador de patrón debe establecerse al final de la expresión regular para que las funciones PCRE de PHP traten la cadena de asunto como UTF-8
codificada Unicode.
Todos juntos entonces, el patrón
/^[\p{Latin}\p{Common}]+$/u
coincidirá con una cadena completa compuesta por uno o más caracteres en los scripts de Unicode latino y común.
Filtrando la cadena de búsqueda
Un buen lugar para interceptar una cadena de búsqueda es la pre_get_posts
acción, ya que se dispara inmediatamente antes de que WordPress ejecute la consulta. Con más cuidado , esto también podría lograrse utilizando 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' );
Responder a búsquedas no permitidas
Una vez que se ha determinado que una cadena de búsqueda contiene caracteres no latinos, puede usarla WP_Query::set()
para modificar la consulta cambiando sus nombres de consulta , lo que afecta la consulta SQL que WordPress posteriormente compone y ejecuta.
Las variables de consulta más relevantes son probablemente las siguientes:
s
es la variable de consulta correspondiente a una cadena de búsqueda. Si se configura como null
una cadena vacía ( ''
), WordPress ya no considerará la consulta como una búsqueda, a menudo esto da como resultado una plantilla de archivo que muestra todas las publicaciones o la página principal del sitio, dependiendo de los valores del otro consulta vars. ' '
Sin embargo, si lo configura en un solo espacio ( ), WordPress lo reconocerá como una búsqueda y, por lo tanto, intentará mostrar la search.php
plantilla.
page_id
podría usarse para dirigir al usuario a una página específica de su elección.
post__in
puede restringir la consulta a una selección específica de publicaciones. Al configurarlo en una matriz con una ID de publicación imposible, puede servir como medida para garantizar que la consulta no devuelva absolutamente nada .
Lo anterior en mente, puede hacer lo siguiente para responder a una búsqueda incorrecta cargando la search.php
plantilla sin resultados:
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' );
Mostrar un error
La forma en que realmente muestra el mensaje de error depende en gran medida de su aplicación y de las capacidades de su tema; hay muchas maneras de hacerlo. Si su tema get_search_form()
aparece en su plantilla de búsqueda, la solución más fácil es probablemente usar un enlace de pre_get_search_form
acción para generar su error inmediatamente arriba del formulario de búsqueda:
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>';
}
Algunas otras posibilidades para mostrar un mensaje de error incluyen:
- Si su sitio usa JavaScript que puede mostrar mensajes "flash" o "modales" (o agrega tales habilidades por su cuenta), agregue la lógica para mostrar mensajes en la carga de la página cuando se establece una variable específica, luego agregue un
wp_enqueue_script
gancho con un valor $priority
mayor que el que pone en cola ese JavaScript, y se usa wp_localize_script()
para configurar esa variable para incluir su mensaje de error.
- Use
wp_redirect()
para enviar al usuario a la URL de su elección (este método requiere una carga de página adicional).
- Establezca una variable PHP o invoque un método que informará a su tema / complemento sobre el error de modo que pueda mostrarlo cuando sea apropiado.
- Establezca la
s
variable de consulta en ''
lugar de ' '
y use page_id
en lugar de post__in
para devolver una página de su elección.
- Use un
loop_start
gancho para inyectar un WP_Post
objeto falso que contenga su error en los resultados de la consulta; este es definitivamente un truco feo y puede no verse bien con su tema en particular, pero tiene el efecto secundario potencialmente deseable de suprimir el mensaje "Sin resultados".
- Use un
template_include
gancho de filtro para intercambiar la plantilla de búsqueda con una personalizada en su tema o complemento que muestre su error.
Sin examinar el tema en cuestión, es difícil determinar qué ruta debe tomar.